Ответ 1
Похоже, что функция glob() зависит от того, как была создана ваша копия PHP и была ли она скомпилирована с помощью WIN32 API с поддержкой Unicode (я не считаю, что стандартный builid есть.
Cf. http://www.rooftopsolutions.nl/blog/filesystem-encoding-and-php
Выдержка из комментариев к статье:
Филипп Верди 2010-09-26 8:53 утра
Выход из вашей установки PHP в Windows легко объяснить: вы установили неверную версию PHP и использовали версию, а не версию скомпилирован для использования Unicode-версии Win32 API. По этой причине, вызовы файловой системы, используемые PHP, будут использовать устаревший API "ANSI" и так библиотеки C/С++, связанные с этой версией PHP, сначала попытаются конвертировать строку UTF-8 с кодировкой UTF-8 в локальную кодовую страницу "ANSI" выбранных в рабочей среде (см. команду CHCP до запуск PHP из окна командной строки)
Ваша версия Windows МОСТ ВЕРОЯТНО НЕ несет ответственности за эту странную вещь. На самом деле, это ВАША версия PHP, которая не скомпилирована правильно, и использует устаревшую версию ANSI версии Win32 API (для совместимость с 16-разрядными версиями Windows 95/98, чьи поддержка файловой системы в ядре фактически не имела прямой поддержки для Unicode, но использовал внутренний уровень конвертации для преобразования Unicode в локальной кодовой страницы ANSI перед использованием фактической версии ANSI API).
Перекомпилируйте PHP, используя параметр компилятора, чтобы использовать версию UNICODE API Win32 (который должен быть сегодня по умолчанию, и в любом случае всегда по умолчанию для PHP, установленного на сервере, который никогда не будет Windows 95 или Windows 98...)
Затем Windows сможет хранить кодированные имена файлов UTF-16 (в том числе на томах FAT32, даже если на этих томах он также будет генерировать сглаженное короткое имя в формате 8.3 с использованием файловой системы по умолчанию кодовой страницы, чего можно избежать в томах NTFS).
Все, что вы описываете, - это проблемы PHP (неправильный перенос на Windows или неправильная идентификация версии системы во время выполнения): перечитайте файлы README, поставляемые с PHP-источниками, объясняющими флагов компиляции. Я действительно думаю, что makefile на Windows должен иметь возможность настраивать и автоматически определять, если действительно нужно использовать ТОЛЬКО ANSI версия API. Если вы компилируете его для сервера, убедитесь, что Configure script будет эффективно обнаруживать полный поддержка UNICODE версии Win32 aPI и будет использовать ее, когда компиляция PHP и выбор библиотек времени выполнения для ссылки.
Я использую PHP на Windows, правильно скомпилирован, и я НЕ НЕ знаю проблемы, которые вы приводите в своей статье.
Давайте забудем теперь навсегда эти версии, не относящиеся к UNICODE для Win32 API (которые необоснованно используют локальную кодовую страницу ANSI для Графический интерфейс пользователя Windows и кодовая страница OEM для API-интерфейсов файловой системы, совместимые с DOS/BIOS API, API-интерфейсы консоли): эти не-Unicode версии API даже МНОГО медленнее и дороже, чем Unicode версии API, потому что они фактически переводят кодовая страница к Unicode перед использованием основных Unicode API ( ситуация на ядрах на базе Windows NT в точности противоположна ситуации в версиях Windows на основе виртуального расширителя DOS, такого как Windows 95/98/ME).
Если вы не используете родную версию API, ваш вызов API будет пройти через слой thunking, который перекодирует строки между Unicode и одна из устаревших кодовых страниц OEM или CHCP, или кодовая страница OEM намекала на файловую систему: для этого требуется дополнительная временное распределение памяти в неродной версии Win32 API. Это занимает дополнительное время, чтобы преобразовать вещи, прежде чем фактическую работу, вызывая собственный API.
Вкратце: двоичный файл PHP, который вы устанавливаете в Windows, ДОЛЖЕН быть другим в зависимости от того, если вы скомпилировали его для Windows 95/98/SE (или старого Уровень эмуляции Win16s для Windows 3.x, который был очень малым поддержка UTF-8, только для поддержки подмножеств Unicode используемого Unicode по кодам ANSI и OEM, выбранным при запуске Windows из DOS extender), или если он был скомпилирован для любой другой версии Windows на ядре NT.
Лучшим доказательством того, что это проблема PHP, а не Windows, является то, что ваши странные результаты не будут встречаться на других языках, таких как С#, Javascript, VB, Perl, Ruby... PHP имеет очень плохую историю в отслеживании версии (и слишком много исторических ошибок исходного кода и неправильных предположения, которые сегодня должны быть отключены, и несогласованная библиотека который унаследовал все эти причуды, изначально сделанные в старых версиях PHP для старых версий Windows, которые даже больше не являются официально поддерживается Microsoft или даже самим PHP!).
Другими словами: RTM! Или загрузите и установите бинарную версию PHP для Windows precompield с правильными настройками: я действительно думаю что PHP должен распространять двоичные файлы Windows, уже скомпилированные по умолчанию для Unicode версии Win32 API, и используя Unicode-версия библиотек C/С++: внутренне код PHP будет конвертировать свои строки UTF-8 в UTF-16 до вызова API Win32 и от UTF-16 до UTF-8 при извлечении результатов Win32 вместо преобразование внутренних строк UTF-8 PHP обратно/в локальную кодовую страницу OEM (для вызовов файловой системы) или локальной кодовой страницы ANSI (для всех остальных Win32 API, включая реестр или процесс).