Как я могу проверить, был ли PHP скомпилирован с UNICODE-версией Win32 API?

10

Это связано с этим постом переполнения стека:

glob () не может найти имена файлов с многобайтовыми символами в Windows?

У меня проблемы с PHP и файлами с многобайтовыми символами в Windows. Вот мой тестовый пример:

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

Правильный вывод на удаленный сервер UNIX:

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
)

Неверный вывод локально в 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
)

Вот соответствующая выдержка из ответа, который я решил принять (на самом деле это цитата из статьи, которая была размещена в сети более 2 лет назад):

Из комментариев к этой статье: http://www.rooftopsolutions.nl/blog/filesystem-encoding-and-php

Вывод вашей установки PHP в Windows легко объяснить: вы установили неправильную версию PHP и использовали версию, не скомпилированную для использования Unicode-версии Win32 API. По этой причине вызовы файловой системы, используемые PHP, будут использовать устаревший API «ANSI», и поэтому библиотеки C / C ++, связанные с этой версией PHP, сначала будут пытаться преобразовать строку PHP в кодировке UTF-8 в локальную «ANSI». кодовая страница, выбранная в рабочей среде (см. команду CHCP перед запуском PHP из окна командной строки)

Ваша версия Windows САМАЯ ВЕРОЯТНО НЕ несет ответственности за эту странную вещь. На самом деле, это ВАША версия PHP, которая неправильно скомпилирована и использует устаревшую ANSI-версию Win32 API (для совместимости с устаревшими 16-разрядными версиями Windows 95/98, поддержка файловой системы в ядре которой фактически не имела прямой поддержка Unicode, но использовал внутренний уровень преобразования для преобразования Unicode в локальную кодовую страницу ANSI перед использованием фактической версии API ANSI).

Перекомпилируйте PHP, используя опцию компилятора, чтобы использовать UNICODE-версию Win32 API (которая должна быть по умолчанию сегодня, и в любом случае всегда по умолчанию для PHP, установленного на сервере, который НИКОГДА не будет Windows 95 или Windows 98 ...)

Я не могу подтвердить, является ли это моей проблемой или нет. Я использовал phpinfo()и не нашел ничего интересного, но я не был уверен, что искать. Я использовал XAMPP для простой установки, поэтому я не совсем уверен, как именно он был установлен.

Я использую 64-битную Windows 7 - так что прости мое невежество, но я даже не уверен, что здесь "Win32" имеет значение. Как я могу проверить, была ли моя текущая версия PHP скомпилирована с конфигурацией, упомянутой выше?

  • Версия PHP : 5.3.8
  • Система : Windows NT WES-PC 6.1 сборка 7601 (Windows 7 Home Premium Edition с пакетом обновления 1) i586
  • Дата постройки: 23 августа 2011 11:47:20
  • Компилятор : MSVC9 (Visual C ++ 2008)
  • Архитектура : x86
  • Настроить команду : 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"

В случае, если это уместно или показывает какую-либо полезную информацию, вот мой скриншот phpinfo()(раздел mbstring):

снимок экрана phpinfo

Как я могу узнать, была ли моя установка PHP "скомпилирована с UNICODE-версией Win32 API"? (и имеет ли это какой-то смысл?)

Уэсли Мерч
источник
5
Проголосовал, потому что Уэсли должен остерегаться друг друга.
Уэсли
Вы сделали что-нибудь в своем сценарии в отношении кодировки? У меня была противоположность этой проблемы с моей установкой win7-64! Php прочитал бы umlats & все это и дерьмовую унаследованную программу, с которой я общался с перерывами, когда получал их.
Крис К
Извините, что отказался от этого вопроса, я просто не получил быстрый и грязный рабочий ответ, на который надеялся, и в конце концов прекратил разработку этого проекта для Windows. Скоро я установлю PHP 5.4 локально (на windows), поэтому вопрос может больше не быть ценным для меня, если кто-то захочет предложить приемлемый ответ, я весь слух. В то же время, голосований и благодарностей всем вокруг.
Уэсли Мёрч,

Ответы:

3

Я думаю, вы должны загрузить официальный двоичный файл из репозитория PHP Windows и установить его (обратите внимание на путь установки).

После этого вам нужно будет настроить apache для использования нового двоичного файла вместо того, которое он переносил по умолчанию. Это просто:

  • Найдите ваш httpd.confфайл в папке WAMP (что-то вроде C: \ wamp \ bin \ apache \ ApacheXXX \ conf \ httpd.conf) - также возможно пройти через traicicon.

  • Хорошо, теперь, когда вы нашли его, найдите строку, соответствующую LoadModule php5_module

  • Хорошо, просто замените эту строку на новую, php5_moduleкоторая, вероятно, находится в c: /php/php5apache2_2.dll (вы сохранили путь установки!). В результате чего-то вродеLoadModule php5_module "c:/php/php5apache2_2.dll"

Вуаля. Перезагрузите сервер wamp и протестируйте ваше приложение с самой последней версией php build специально для windows.

Я не уверен, что это решит вашу проблему, но, безусловно, это реальный путь. Если у вас есть проблемы с настройкой php, прочитайте эту статью .

Удачи!

Тьяго Маседо
источник
2

Кажется, что этот вопрос уже давно существует, и то, был ли php скомпилирован с флагами Unicode, не влияет на его поддержку Unicode, но если вам нужно определить, был ли данный PE-образ скомпилирован с версией Unicode Windows API, вы можете использовать, dumpbinчтобы изучить используемый импорт kernel32.dll. Это не совсем то, что я бы сделал прагматично, но в крайнем случае, может работать для диагностики.

Например, исполняемый файл Unicode может перечислить:

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

отмечая количество функций, оканчивающихся на W, то есть Wide для символов юникода.

Для исполняемого файла ANSI или DLL вы можете увидеть что-то ближе к:

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

с большинством функций, оканчивающихся на A, мы видим, что исполняемый файл, скорее всего, был скомпилирован с флагами ANSI.

Митч
источник
2

Вот код, над которым я работал, чтобы mbstringрешить проблему, с которой столкнулся. В итоге я перебрал каждую комбинацию кодировок и опций, пока один из них не представил нужный мне результат. Я чувствую, что такая процедура может помочь вам найти ответ, который вы ищете.

Не полагайтесь на документацию , так как в моем случае результаты были не такими, как я думал, что варианты и кодировки подойдут. Я помню, что в моем тестировании я получал прямоугольники,? И такие вещи, как A ~. Мое тестирование было точно таким же, как ваше, print_rинформация. В моем случае мой скрипт импортирует информацию о клиентах и ​​продажах в Quickbooks, которые не могут обрабатывать UTF-8. (Либо сам QB не может, либо драйвер QODBC не может) Тильды, могилы и умлаты исключены.

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

Эта ссылка выше http://www.php.net/manual/en/function.mb-detect-encoding.php#89915, и если Google найдет вас здесь, обязательно прочитайте это.

Крис К
источник
1

Я полагаю, что вы захотите проверить, был ли PHP скомпилирован с помощью mbstring (или если модуль mbstring установлен и включен, если вы используете модули). Включение этого расширения должно решить ваши проблемы. Эта страница должна рассказать вам все, что вам нужно знать, чтобы она заработала.

Аарон
источник
Спасибо за предложение, но я считаю, что mbstring установлен правильно. Я добавил немного информации об этом в конце своего поста. Мне больше интересно узнать о комментариях, которые я цитировал в статье «ВАША версия PHP, которая неправильно скомпилирована и использует устаревшую ANSI-версию Win32 API» , как узнать, так ли это, и актуально это или нет.
Уэсли Мёрч
Я не думаю, что поддержка Unicode в PHP имеет много общего с поддержкой Unicode в API, который PHP использует для своей деятельности. Я подозреваю, что последнее является проблемой, а не первым. (Извините, что у меня нет ответа на проблему; мне противно, насколько ужасен PHP после того, как попробовал вменяемые языки, поэтому у меня не так много опыта с этим).
gparent