Come posso verificare se PHP è stato compilato con la versione UNICODE dell'API Win32?


10

Questo è correlato a questo post Stack Overflow:

glob () non riesci a trovare i nomi dei file con caratteri multibyte su Windows?

Sto riscontrando problemi con PHP e file con caratteri multibyte su Windows. Ecco il mio caso di test:

print_r(scandir('./uploads/')); 
print_r(glob('./uploads/*'));

Output corretto sul server UNIX remoto:

Array
(
    [0] => .
    [1] => ..
    [2] => filename-äöü.jpg
    [3] => filename.jpg
    [4] => test이test.jpg
    [5] => имя файла.jpg
    [6] => פילענאַמע.jpg
    [7] => 文件名.jpg
)
Array
(
    [0] => ./uploads/filename-äöü.jpg
    [1] => ./uploads/filename.jpg
    [2] => ./uploads/test이test.jpg
    [3] => ./uploads/имя файла.jpg
    [4] => ./uploads/פילענאַמע.jpg
    [5] => ./uploads/文件名.jpg
)

Output errato localmente su Windows:

Array
(
    [0] => .
    [1] => ..
    [2] => ??? ?????.jpg
    [3] => ???.jpg
    [4] => ?????????.jpg
    [5] => filename-äöü.jpg
    [6] => filename.jpg
    [7] => test?test.jpg
)
Array
(
    [0] => ./uploads/filename-äöü.jpg
    [1] => ./uploads/filename.jpg
)

Ecco un estratto pertinente della risposta che ho scelto di accettare (che in realtà è una citazione da un articolo che è stato pubblicato online più di 2 anni fa):

Dai commenti su questo articolo: http://www.rooftopsolutions.nl/blog/filesystem-encoding-and-php

L'output della tua installazione di PHP su Windows è facile da spiegare: hai installato una versione errata di PHP e hai utilizzato una versione non compilata per utilizzare la versione Unicode dell'API Win32. Per questo motivo, le chiamate al filesystem utilizzate da PHP useranno l'API "ANSI" legacy e quindi le librerie C / C ++ collegate a questa versione di PHP proveranno prima a convertire la stringa PHP con codifica UTF-8 nella "ANSI" locale tabella codici selezionata nell'ambiente in esecuzione (consultare il comando CHCP prima di avviare PHP da una finestra della riga di comando)

La tua versione di Windows NON È PROBABILMENTE NON responsabile di questa strana cosa. In realtà, questa è la TUA versione di PHP che non è stata compilata correttamente e che utilizza la versione ANSI legacy dell'API Win32 (per la compatibilità con le versioni legacy a 16 bit di Windows 95/98 il cui supporto del filesystem nel kernel in realtà non aveva diretto supporto per Unicode, ma ha utilizzato un livello di conversione interno per convertire Unicode nella tabella codici ANSI locale prima di utilizzare la versione ANSI effettiva dell'API).

Ricompila PHP usando l'opzione del compilatore per utilizzare la versione UNICODE dell'API Win32 (che dovrebbe essere quella predefinita oggi, e comunque sempre quella predefinita per PHP installato su un server che non sarà MAI Windows 95 o Windows 98 ...)

Non posso confermare se questo è il mio problema o no. Ho usato phpinfo()e non ho trovato nulla di interessante, ma non ero sicuro di cosa cercare. Ho usato XAMPP per installazioni facili, quindi non sono sicuro di come sia stato installato.

Sto usando Windows 7, 64 bit - quindi perdona la mia ignoranza, ma non sono nemmeno sicuro se "Win32" è rilevante qui. Come posso verificare se la mia versione attuale di PHP è stata compilata con la configurazione sopra menzionata?

  • Versione PHP : 5.3.8
  • Sistema : Windows NT WES-PC 6.1 build 7601 (Windows 7 Home Premium Edition Service Pack 1) i586
  • Data di costruzione : 23 agosto 2011 11:47:20
  • Compilatore : MSVC9 (Visual C ++ 2008)
  • Architettura : x86
  • Configura comando : cscript /nologo configure.js "--enable-snapshot-build" "--disable-isapi" "--enable-debug-pack" "--disable-isapi" "--without-mssql" "--without-pdo-mssql" "--without-pi3web" "--with-pdo-oci=D:\php-sdk\oracle\instantclient10\sdk,shared" "--with-oci8=D:\php-sdk\oracle\instantclient10\sdk,shared" "--with-oci8-11g=D:\php-sdk\oracle\instantclient11\sdk,shared" "--enable-object-out-dir=../obj/" "--enable-com-dotnet" "--with-mcrypt=static" "--disable-static-analyze"

Se è pertinente o rivela informazioni utili, ecco una mia schermata phpinfo()(sezione mbstring):

schermata phpinfo

Come posso sapere se la mia installazione di PHP è stata "compilata con la versione UNICODE dell'API Win32"? (e ha davvero senso?)


5
Eseguito l'upgrade perché i Wesley devono stare attenti.
Wesley,

Hai fatto qualcosa nel tuo script per quanto riguarda la codifica? Ho avuto l'opposto di questo problema con la mia installazione win7-64! Php avrebbe letto gli umlats e tutto il resto e il programma legacy di merda che stavo comunicando con le pause quando li riceve.
Chris K,

Scusatemi per aver lasciato su questa domanda, non ho avuto la risposta rapida e sporca che speravo, e alla fine ho smesso di sviluppare questo progetto su Windows. Presto installerò PHP 5.4 localmente (su Windows), quindi la domanda potrebbe non essere più preziosa per me, se qualcuno vuole suggerire una risposta accettata, sono tutto a posto. Nel frattempo, voti positivi e ringraziamenti.
Wesley Murch,

Risposte:


3

Penso che dovresti scaricare un binario ufficiale dal repository di Windows PHP e installarlo (prendere nota del percorso di installazione).

Dopodiché dovrai configurare apache per usare il nuovo binario invece di quello che portava di default. È semplice:

  • Trova il tuo httpd.conffile nella cartella WAMP (qualcosa come C: \ wamp \ bin \ apache \ ApacheXXX \ conf \ httpd.conf) - potrebbe anche essere possibile passare attraverso trayicon.

  • Ok, ora che l'hai trovato trova una stringa corrispondente LoadModule php5_module

  • Bene, basta sostituire questa riga con la nuova php5_moduleche è in modo probaly in c: /php/php5apache2_2.dll (hai salvato il percorso di installazione!). Ne risulta qualcosa di simileLoadModule php5_module "c:/php/php5apache2_2.dll"

Ecco. Ripristina il server wamp e testa la tua applicazione con l'ultima versione di php build appositamente per Windows.

Non sono sicuro che questo risolverà il tuo problema, ma sicuramente è una vera strada da percorrere. Se hai problemi con l'installazione di php, leggi questo articolo .

In bocca al lupo!


2

Sembra che questa domanda sia in circolazione da un po 'di tempo e se php sia stato compilato o meno con flag unicode non influisca sul suo supporto unicode, ma se è necessario determinare se una determinata immagine PE è stata probabilmente compilata sulla versione Unicode della API di Windows, è possibile utilizzare dumpbinper esaminare le importazioni kernel32.dll utilizzate. Questo non è esattamente qualcosa che farei pragmaticamente, ma in un pizzico, potrebbe funzionare per la diagnostica.

Ad esempio, un eseguibile Unicode potrebbe elencare:

               4C CreateFileMappingW
               45 CreateDirectoryW
               33 CompareStringW
              12E GetCurrentDirectoryW
               AF ExpandEnvironmentStringsW
              2F0 SetFileAttributesW

rilevando il numero di funzioni che terminano in W, aka Wide per i caratteri unicode.

Per un eseguibile ANSI o una DLL, potresti vedere qualcosa di più vicino a:

              30A SetCurrentDirectoryA
              15E GetFileAttributesA
              171 GetLastError
               4B CreateDirectoryA
              319 SetFileAttributesA

con la maggior parte delle funzioni che terminano con A, possiamo vedere che l'eseguibile è stato probabilmente compilato con flag ANSI.


2

Ecco del codice su cui ho lavorato per gestire un mbstringproblema in cui mi trovavo. Ho finito per iterare attraverso ogni combinazione di codifiche e opzioni fino a quando uno di loro ha presentato l'output di cui avevo bisogno. Ho la sensazione che questo tipo di procedura possa aiutarti a trovare la risposta che stai cercando.

Non fare affidamento sulla documentazione , come nel mio caso, i risultati non erano quelli che pensavo avrebbero fatto le opzioni e le codifiche. Ricordo nei miei test, avrei ottenuto i rettangoli,? S, e cose come A ~. Il mio test è stato esattamente come il tuo, print_rl'informazione. Nel mio caso, il mio script sta importando le informazioni sui clienti e sulle vendite in Quickbooks, che non è in grado di gestire UTF-8. (Né QB stesso non può o il driver QODBC non può) Tilde, tombe e umlat sono fuori questione.

setlocale(LC_CTYPE, 'en_US.UTF-8');
$xmlstr=file_get_contents($file);           
// convert character encoding to get rid of accents, etc
// see http://www.php.net/manual/en/function.mb-detect-encoding.php#89915
// note that unlike ASCII//TRANSLIT and ASCII//TRANSLIT//IGNORE do not work
// in windows 7.
$xmlstr=iconv('UTF-8', 'ASCII//IGNORE', $xmlstr);   

Quel link qui sopra è http://www.php.net/manual/en/function.mb-detect-encoding.php#89915 e se Google ti trova qui, sicuramente vai a leggerlo.


1

Credo che vorrai verificare se PHP è stato compilato con mbstring (o se il modulo mbstring è installato e abilitato se stai usando i moduli). L'attivazione di tale estensione dovrebbe risolvere i tuoi problemi. Questa pagina dovrebbe dirti tutto ciò che devi sapere per farlo funzionare.


Grazie per il suggerimento, ma credo che mbstring sia installato correttamente. Ho aggiunto alcune informazioni al riguardo alla fine del mio post. Sono più interessato a conoscere i commenti che ho citato dall'articolo "LA TUA versione di PHP che non è stata compilata correttamente e che utilizza la versione ANSI legacy dell'API Win32" , come scoprire se è così, e se questo è rilevante.
Wesley Murch,

Non credo che il supporto unicode in PHP abbia molto a che fare con il supporto unicode nell'API che PHP usa per fare la propria attività. Sospetto che quest'ultimo sia il problema piuttosto che il primo. (Mi dispiace però non avere una risposta al problema; sono disgustato da quanto sia terribile PHP dopo aver provato linguaggi sani, quindi non ho molta esperienza con esso).
gparent,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.