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

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

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

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

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

[Сб, 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 ') в Unknown в строке 0

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

ИЗМЕНИТЬ

Удалена информация о переписывании URL-адресов, так как это не похоже на фактор.

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


person Raleigh    schedule 02.04.2009    source источник


Ответы (5)


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

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

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

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

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

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

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

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

person David Earl    schedule 11.12.2009
comment
вы МОЖЕТЕ заставить php открыть файл, просканировав каталог и используя найденное имя, даже если оно находится в другой кодировке. - person Timo Huovinen; 27.11.2010
comment
stackoverflow.com/questions/1525830/ -› Я бы проверил это здесь - person Revenant; 11.12.2011

  • Я точно знаю, что сам PHP может работать с URL-адресами Unicode, потому что я пробовал использовать имена страниц Unicode в MediaWiki (на основе PHP, также работает WikiPedia), и это действительно работает. Например, URL-адреса, такие как /index.php/Page_name ©. Так что 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.

person thomasrutter    schedule 02.04.2009

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

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

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

person Fire Crow    schedule 02.04.2009

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

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

person Tristanisginger    schedule 05.06.2013

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

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

person Vitalicus    schedule 22.02.2015