Может ли имя файла PHP (или каталог в его полном пути) иметь символы UTF-8? - PullRequest
11 голосов
/ 02 апреля 2009

Я хотел бы получить доступ к файлу PHP, имя которого содержит символы UTF-8.

В файле нет спецификации. Он просто содержит оператор echo, отображающий несколько символов Юникода.

Доступ к странице PHP из браузера (FireFox 3.0.8, IE7) приводит к ошибке HTTP 500.

В журнале Apache есть две записи (файл / க. Php; буква க является составной и соответствует символам \ xe0 \ xae \ x95 в журнале ниже):

[Сб. 04 04.09:30:25 2009] [ошибка] [клиент 127.0.0.1] Предупреждение PHP: Неизвестно: не удалось открыть поток: Нет такого файла или каталога в Неизвестно в строке 0

[Сб. 04 апреля 09:30:25 2009] [ошибка] [клиент 127.0.0.1] Неустранимая ошибка PHP: неизвестно: не удалось открыть файл 'D: / va / ROOT / \ xe0 \ xae \ x95.php' ( include_path = '.; C: \ php5 \ pear') в поле Неизвестно в строке 0

Та же страница работает, когда имена файлов и папок на английском языке. В той же настройке нет проблем с использованием SSI для этих страниц.

EDIT

Удалена информация о переписывании URL, поскольку это не имеет значения.

При удалении mod_rewrite файл PHP по-прежнему не работает. Работает, если файл переименован в имя, отличное от UTF. Однако shtml работает даже с UTF-символами в имени файла и / или пути.

Ответы [ 5 ]

15 голосов
/ 11 декабря 2009

Я столкнулся с той же проблемой, провел некоторое исследование и пришел к выводу следующее. Это для php5 на Windows; это вероятно верно для других платформ, но я не проверял.

  1. ВСЕ функции файловой системы php (dir, is_dir, is_file, file, filemtime, filesize, file_exists и т. Д.) Принимают и возвращают только имена файлов в ISO-8859-1, независимо от набора default_charset, установленного в программе или ini. файлы.

  2. Если имя файла содержит Unicode-символ dir-> read, он будет возвращен как соответствующий символ ISO-8859-1, если таковой имеется, в противном случае он будет заменять знак вопроса.

  3. При ссылке на файл, например, в is_file или file, если вы передадите имя файла UTF-8, файл не будет найден, если имя содержит любые двухбайтовые или более символов. Однако is_file (utf8_decode ($ filename)) и т. Д. Будут работать при условии представления символа UTF-8 в ISO-8859-1.

Другими словами, PHP5 вообще не способен адресовать файлы с многобайтовыми символами в именах.

Если запрашивается URL-адрес UTF-8 с многобайтовыми символами, и это напрямую соответствует файлу, PHP не сможет открыть файл, поскольку не может адресовать его.

Если вам просто нужны красивые URL-адреса на вашем языке, предложение использования mod_rewrite кажется хорошим.

Но если вы храните и извлекаете файлы, загруженные и загруженные пользователями, эта проблема должна быть решена. Одним из способов является использование произвольного (не UTF-8) имени файла, такого как инкремент, на сервере и индексация файлов в базе данных или XML-файле или некоторых других. Другой способ - хранить файлы в самой базе данных как BLOB. Другой способ (который, возможно, легче увидеть, что происходит, и не вызывает проблем, если ваш индекс поврежден) - это самостоятельно кодировать имена файлов. Хорошая техника - это urlencode (sic) всех ваших входящих файлов при хранении на сервере. диск и urldecode их перед установкой имени файла в заголовке MIME для загрузки. Все даже смутно необычные символы (кроме%) затем кодируются как% nn, поэтому любые проблемы с пробелами в именах файлов, межплатформенная поддержка и сопоставление с образцом в значительной степени исключаются.

6 голосов
/ 02 апреля 2009
  • Я точно знаю, что сам PHP может работать с URL-адресами Unicode, потому что я пытался использовать имена страниц Unicode в MediaWiki (на основе PHP, также запускает WikiPedia), и он работает. Например, URL-адреса, такие как /index.php/Page_namemail. Так что PHP может справиться с этим. Но это может быть проблемой с Apache, который находит файл, в котором исходный файл имеет имя UTF-8.

  • Настройка PHP.ini для кодировки символов не должна влиять на это; работа веб-сервера заключается в том, чтобы найти конкретный ресурс и затем вызвать PHP, если он определен как файл PHP. Это будет означать, что веб-сервер и сама основная файловая система должны иметь возможность работать с именами файлов UTF-8.

  • Работает ли без правила mod_rewrite? То есть, если вы отключите механизм перезаписи с выключенным RewriteEngine, а затем запросите va.in/utf_dir/utf_file.php? Если это так, то это может быть проблема конфигурации mod_rewrite или проблема с правилом.

  • Юникод в URL может не поддерживаться должным образом в некоторых браузерах, когда вы просто вводите адрес, например в старых браузерах. Старые браузеры могут пропустить этап кодирования UTF-8. Это не должно мешать его работе, если вы переходите по ссылке на странице, где эта страница имеет кодировку UTF-8.

2 голосов
/ 02 апреля 2009

Тот факт, что набор символов UTF-8 не означает, что он поддерживает все более высокие символы Unicode.

Поддержка Unicode является одним из основных дополнений, появившихся в PHP 6, а PHP 5 питает недостаток поддержки Unicode.

Если ваш PHP-скрипт генерирует ссылку, это может быть другой проблемой, чем если бы Apache интерпретировал URL-адрес напрямую и перенаправил его.

1 голос
/ 05 июня 2013

Нет. Имена файлов PHP должны быть в ASCII, не имеет значения, как вы настраиваете свой сервер. PHP5 не может справиться с этим, поэтому мы ждем PHP 6. В сценарии PHP вы можете обрабатывать имя файла / URL utf-8, используя utf8_decode. Вы можете использовать .htaccess и SQL, чтобы обойти множество проблем, но нет способа запустить имя файла в юникоде.

Ответ Дэвида Эрла правильный.

0 голосов
/ 22 февраля 2015

Используйте "wfio: //" для копирования записи, e.t.c.

https://github.com/kenjiuno/php-wfio

Для папки:

.htaccess:

php_value auto_prepend_file C:/fix.php

fix.php:

$file = $_SERVER['SCRIPT_FILENAME'];
if (!is_readable($file)) {
    $file="wfio://".$file;
                include $file;
                exit;
        }

Но лучше для php использовать ОС Linux

...