Comment puis-je vérifier si PHP a été compilé avec la version UNICODE de l'API Win32?

10

Ceci est lié à ce post Stack Overflow:

glob () ne trouve pas les noms de fichiers avec des caractères multi-octets sous Windows?

J'ai des problèmes avec PHP et les fichiers contenant des caractères multi-octets sous Windows. Voici mon cas de test:

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

Sortie correcte sur le serveur UNIX distant:

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
)

Sortie incorrecte localement sous 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
)

Voici un extrait pertinent de la réponse que j'ai choisi d'accepter (qui est en fait une citation d'un article publié en ligne il y a plus de 2 ans):

D'après les commentaires sur cet article: http://www.rooftopsolutions.nl/blog/filesystem-encoding-and-php

La sortie de votre installation PHP sur Windows est facile à expliquer: vous avez installé la mauvaise version de PHP et utilisé une version non compilée pour utiliser la version Unicode de l'API Win32. Pour cette raison, les appels du système de fichiers utilisés par PHP utiliseront l'ancienne API "ANSI" et donc les bibliothèques C / C ++ liées à cette version de PHP essaieront d'abord de convertir votre chaîne PHP encodée en UTF-8 en "ANSI" local page de code sélectionnée dans l'environnement d'exécution (voir la commande CHCP avant de démarrer PHP à partir d'une fenêtre de ligne de commande)

Votre version de Windows n'est PLUS PROBABLEMENT PAS responsable de cette chose étrange. En fait, c'est VOTRE version de PHP qui n'est pas compilée correctement, et qui utilise la version ANSI héritée de l'API Win32 (pour la compatibilité avec les versions 16 bits héritées de Windows 95/98 dont la prise en charge du système de fichiers dans le noyau n'avait en fait pas de lien direct prise en charge d'Unicode, mais utilisé une couche de conversion interne pour convertir Unicode en page de code ANSI locale avant d'utiliser la version ANSI réelle de l'API).

Recompilez PHP en utilisant l'option du compilateur pour utiliser la version UNICODE de l'API Win32 (qui devrait être la valeur par défaut aujourd'hui, et de toute façon toujours la valeur par défaut pour PHP installé sur un serveur qui ne sera JAMAIS Windows 95 ou Windows 98 ...)

Je ne peux pas confirmer si c'est mon problème ou non. J'ai utilisé phpinfo()et je n'ai rien trouvé d'intéressant, mais je ne savais pas trop quoi chercher. J'utilise XAMPP pour des installations faciles, donc je ne sais vraiment pas exactement comment il a été installé.

J'utilise Windows 7, 64 bits - pardonnez donc mon ignorance, mais je ne sais même pas si "Win32" est pertinent ici. Comment puis-je vérifier si ma version actuelle de PHP a été compilée avec la configuration mentionnée ci-dessus?

  • Version PHP : 5.3.8
  • Système : Windows NT WES-PC 6.1 build 7601 (Windows 7 Home Premium Edition Service Pack 1) i586
  • Date de construction : 23 août 2011 11:47:20
  • Compilateur : MSVC9 (Visual C ++ 2008)
  • Architecture : x86
  • Configurer la commande : 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"

Dans le cas où cela est pertinent ou révèle des informations utiles, voici une capture d'écran de ma phpinfo()(section mbstring):

capture d'écran phpinfo

Comment savoir si mon installation PHP a été "compilée avec la version UNICODE de l'API Win32"? (et est-ce que cela a un sens?)

Wesley Murch
la source
5
Voté parce que Wesley doit faire attention les uns aux autres.
Wesley
Avez-vous fait quelque chose dans votre script en ce qui concerne l'encodage? J'ai eu l'opposé de ce problème avec mon installation win7-64! Php lirait les umlats et tout ça et le programme hérité de merde que je communiquais avec les pauses quand il les avait.
Chris K
Désolé de répondre à cette question, je n'ai tout simplement pas obtenu la réponse rapide et sale que j'espérais, et j'ai finalement arrêté de développer ce projet sur Windows. Je vais bientôt installer PHP 5.4 localement (sur Windows), donc la question pourrait ne plus avoir de valeur pour moi, si quelqu'un veut suggérer une réponse acceptée, je suis à l'écoute. En attendant, des votes positifs et merci tout autour.
Wesley Murch

Réponses:

3

Je pense que vous devriez télécharger un binaire officiel à partir du référentiel PHP Windows et l'installer (notez le chemin d'installation).

Après cela, vous devrez configurer apache pour utiliser le nouveau binaire au lieu de celui qu'il portait par défaut. C'est simple:

  • Recherchez votre httpd.conffichier dans le dossier WAMP (quelque chose comme C: \ wamp \ bin \ apache \ ApacheXXX \ conf \ httpd.conf) - il peut également être possible de passer par trayicon.

  • Ok, maintenant que vous l'avez trouvé, recherchez une chaîne correspondant LoadModule php5_module

  • Bon, remplacez simplement cette ligne par votre nouvelle php5_modulequi est probablement dans c: /php/php5apache2_2.dll (vous avez enregistré le chemin d'installation!). Résultant en quelque chose commeLoadModule php5_module "c:/php/php5apache2_2.dll"

Voila. Réinitialisez le serveur Wamp et testez votre application avec la dernière version de php build spécialement pour Windows.

Je ne suis pas sûr que cela résoudra votre problème, mais c'est certainement une vraie voie à suivre. Si vous avez des problèmes avec la configuration php, lisez cet article .

Bonne chance!

Thiago Macedo
la source
2

Il semble que cette question existe depuis un certain temps et si oui ou non le php a été compilé avec des drapeaux unicode n'affecte pas sa prise en charge unicode, mais si vous devez déterminer si une image PE donnée a probablement été compilée avec la version Unicode du API Windows, vous pouvez utiliser dumpbinpour examiner les importations kernel32.dll utilisées. Ce n'est pas exactement quelque chose que je ferais de manière pragmatique, mais à la rigueur, cela pourrait fonctionner pour les diagnostics.

Par exemple, un exécutable Unicode pourrait répertorier:

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

notant le nombre de fonctions se terminant par W, alias Wide pour les caractères unicode.

Pour un exécutable ou une DLL ANSI, vous pouvez voir quelque chose de plus proche de:

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

avec la plupart des fonctions se terminant par A, nous pouvons voir que l'exécutable a probablement été compilé avec des drapeaux ANSI.

Mitch
la source
2

Voici du code sur lequel j'ai travaillé pour gérer un mbstringproblème que je rencontrais. J'ai fini par parcourir toutes les combinaisons d'encodages et d'options jusqu'à ce que l'un d'eux présente la sortie dont j'avais besoin. J'ai l'impression que ce genre de procédure pourrait vous aider à trouver la réponse que vous cherchez.

Ne vous fiez pas à la documentation , car dans mon cas, les résultats n'étaient pas ce que je pensais que les options et les encodages feraient. Je me souviens dans mes tests, j'obtiendrais les rectangles, les s et des choses comme A ~. Mes tests étaient exactement les vôtres, print_rl'info. Dans mon cas, mon script importe des informations sur les clients et les ventes dans Quickbooks, qui ne peut pas gérer UTF-8. (Soit QB lui-même ne le peut pas, soit le pilote QODBC ne peut pas) Les tildes, les tombes et les umlats sont hors de question.

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);   

Ce lien ci-dessus est http://www.php.net/manual/en/function.mb-detect-encoding.php#89915 et si Google vous trouve ici, allez certainement le lire.

Chris K
la source
1

Je pense que vous voudrez vérifier si PHP a été compilé avec mbstring (ou si le module mbstring est installé et activé si vous utilisez des modules). L'activation de cette extension devrait résoudre vos problèmes. Cette page devrait vous dire tout ce que vous devez savoir pour le faire fonctionner.

Aaron
la source
Merci pour la suggestion, mais je pense que mbstring est installé correctement. J'ai ajouté quelques informations à ce sujet à la fin de mon post. Je suis plus intéressé à en savoir plus sur les commentaires que j'ai cités dans l'article "VOTRE version de PHP qui n'est pas compilée correctement et qui utilise la version ANSI héritée de l'API Win32" , comment savoir si c'est le cas, et que cela soit pertinent ou non.
Wesley Murch
Je ne pense pas que la prise en charge unicode en PHP ait beaucoup à voir avec la prise en charge unicode dans l'API que PHP utilise pour faire ses affaires. Je soupçonne que ce dernier est le problème plutôt que le premier. (Désolé cependant, je n'ai pas de réponse au problème; je suis dégoûté de voir à quel point PHP est horrible après avoir essayé des langages sains, donc je n'ai pas autant d'expérience avec cela).
gparent