Назад | Перейти на главную страницу

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

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

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
)

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

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

Результат установки PHP в Windows легко объяснить: вы установили неправильную версию PHP и использовали версию, не скомпилированную для использования версии 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 перед использованием фактической версии ANSI API).

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

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

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

  • Версия PHP: 5.3.8
  • Система: Windows NT WES-PC 6.1 build 7601 (Windows 7 Home Premium Edition Service Pack 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):

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

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

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

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

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

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

Вуаля. Перезагрузите сервер wamp и протестируйте свое приложение с помощью последней версии сборки php специально для Windows.

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

Удачи!

Вот код, над которым я работал, чтобы обработать 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 найдет вас здесь, обязательно прочтите это.

Кажется, что этот вопрос существует уже некоторое время, и был ли 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.

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