Как открыть файл на PHP, который имеет символы Unicode в его имени?

Например, у меня есть такое имя файла – проба.xml, и я не могу открыть его из PHP-скрипта.

Если я установил php-скрипт в utf-8, все тексты в скрипте будут utf-8, поэтому, когда я передаю это файлу file_get_contents:

$fname = "проба.xml"; file_get_contents($fname); 

Я получаю ошибку, что файл не существует. Причина этого в том, что в Windows (XP) все имена файлов с нелатинскими символами являются unicode (UTF-16). ОК, поэтому я попробовал это:

 $fname = "проба.xml"; $res = mb_convert_encoding($fname,'UTF-8','UTF-16'); file_get_contents($res); 

Но ошибка сохраняется, поскольку file_get_contents не могут принимать строки Unicode …

Какие-либо предложения?

ОБНОВЛЕНИЕ (13 июля 17)

Хотя документы, похоже, не упоминают об этом, PHP 7.0 и выше, наконец, поддерживают имена файлов Unicode в Windows из коробки. API-интерфейсы файловой системы PHP принимают и возвращают имена файлов в соответствии с default_charset , что по умолчанию является UTF-8 .

Обратитесь к исправлению ошибок здесь: https://github.com/php/php-src/commit/3d3f11ede4cc7c83d64cc5edaae7c29ce9c6986f


ОБНОВЛЕНИЕ (29 января 15)

Если у вас есть доступ к каталогу расширений PHP, вы можете попробовать установить php-wfio.dll адресу https://github.com/kenjiuno/php-wfio и обратиться к файлам через протокол wfio:// .

 file_get_contents("wfio://你好.xml"); 

Оригинальный ответ

PHP в Windows использует устаревшие «ANSI API» исключительно для локального доступа к файлам, что означает, что PHP использует System Locale вместо Unicode.

Для доступа к файлам, имена файлов которых содержат Unicode, вы должны преобразовать имя файла в указанную кодировку для текущего системного языка. Если имя файла содержит символы, которые не представлены в указанной кодировке, вам не повезло (обновление: см. Раздел выше для решения) . scandir вернет тарабарщину для этих файлов, и передача строки обратно в fopen и эквиваленты не удастся.

Чтобы найти правильную кодировку для использования, вы можете получить локаль системы, вызвав <?=setlocale(LC_TYPE,0)?> И просмотрев идентификатор <?=setlocale(LC_TYPE,0)?> страницы (номер после . ) В статье MSDN https: // msdn.microsoft.com/en-us/library/dd317756(VS.85).aspx .

Например, если функция возвращает Chinese (Traditional)_HKG.950 , это означает, что используется кодовая страница 950, и имя файла должно быть преобразовано в кодировку big-5. В этом случае ваш код должен быть следующим, если ваш файл сохранен в UTF-8 (желательно без спецификации):

 $fname = iconv('UTF-8','big-5',"你好.xml"); file_get_contents($fname); 

или следующим образом, если вы непосредственно сохраняете файл как Big-5:

 $fname = "你好.xml"; file_get_contents($fname); 

Вы можете попробовать:

  • получение строки для имени файла из списка каталогов с использованием opendir и readdir
  • передав эту строку в файл_get_contents, чтобы увидеть, будет ли это работать, или
  • попробуйте получить содержимое файла, используя fopen, fread и fclose

Надеюсь это поможет!

Это выводы до сих пор:

  1. PHP 5 не может открыть имя файла с символами Unicode, если исходное имя файла не является unicode.
  2. PHP 5 (по крайней мере, в Windows XP) не может обрабатывать PHP-источник в юникоде.

Таким образом, вывод это не выполнимо в PHP 5.