apache PHP 文件名(或其完整路径中的目录)可以包含 UTF-8 字符吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/708017/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 17:26:53  来源:igfitidea点击:

Can a PHP file name (or a dir in its full path) have UTF-8 characters?

phpapacheunicodeutf-8url-rewriting

提问by Raleigh

I would like to access a PHP file whose name has UTF-8 characters in it.

我想访问名称中包含 UTF-8 字符的 PHP 文件。

The file does not have a BOM in it. It just contains an echo statement that displays a few unicode characters.

该文件中没有 BOM。它只包含一个显示几个 unicode 字符的 echo 语句。

Accessing the PHP page from the browser (FireFox 3.0.8, IE7) results in HTTP error 500.

从浏览器(FireFox 3.0.8、IE7)访问 PHP 页面会导致 HTTP 错误 500。

There are two entries in the Apache log (file is /?.php; the letter ? is a composite one and corresponds to the characters \xe0\xae\x95 in the log below):

Apache日志中有两个条目(文件是/?.php;字母?是一个复合条目,对应下面日志中的字符\xe0\xae\x95):

[Sat Apr 04 09:30:25 2009] [error] [client 127.0.0.1] PHP Warning: Unknown: failed to open stream: No such file or directory in Unknown on line 0

[Sat Apr 04 09:30:25 2009] [error] [client 127.0.0.1] PHP Warning: Unknown: failed to open stream: No such file or directory in Unknown on line 0

[Sat Apr 04 09:30:25 2009] [error] [client 127.0.0.1] PHP Fatal error: Unknown: Failed opening required 'D:/va/ROOT/\xe0\xae\x95.php' (include_path='.;C:\php5\pear') in Unknown on line 0

[Sat Apr 04 09:30:25 2009] [error] [client 127.0.0.1] PHP Fatal error: Unknown: Failed opening required 'D:/va/ROOT/\xe0\xae\x95.php' (include_path=' .;C:\php5\pear') 在第 0 行的 Unknown

The same page works when file and dir names are in English. In the same setup, there is no problem using SSI for these pages.

当文件和目录名称为英文时,相同的页面有效。在相同的设置中,对这些页面使用 SSI 没有问题。

EDIT

编辑

Removed info on url rewriting since it does not seem to be a factor.

删除了关于 url 重写的信息,因为它似乎不是一个因素。

When mod_rewrite is removed, the PHP file still does not work. Works if the file is renamed to a non-UTF name. However, shtml works even with UTF characters in file and/or path name.

当 mod_rewrite 被移除时,PHP 文件仍然不起作用。如果文件重命名为非 UTF 名称,则有效。但是,shtml 甚至可以在文件和/或路径名中使用 UTF 字符。

回答by David Earl

I have come across the same problem and done some research and conclude the following. This is for php5 on Windows; it is probably true on other platforms but I haven't checked.

我遇到了同样的问题并做了一些研究并得出以下结论。这适用于 Windows 上的 php5;在其他平台上可能是这样,但我没有检查过。

  1. ALL php file system functions (dir, is_dir, is_file, file, filemtime, filesize, file_exists etc) only accept and return file names in ISO-8859-1, irrespective of the default_charset set in the program or ini files.

  2. Where a filename contains a unicode character dir->read will return it as the corresponding ISO-8859-1 character if there is one, otherwise it will substitute a question mark.

  3. When referencing a file, e.g. in is_file or file, if you pass in a UTF-8 file name the file will not be found when the name contains any two-byte or more characters. However, is_file(utf8_decode($filename)) etc will work providing the UTF-8 character is representable in ISO-8859-1.

  1. 所有 php 文件系统函数(dir、is_dir、is_file、file、filemtime、filesize、file_exists 等)只接受和返回 ISO-8859-1 中的文件名,而不管程序或 ini 文件中的 default_charset 设置如何。

  2. 如果文件名包含 unicode 字符 dir->read ,则将其作为相应的 ISO-8859-1 字符返回,否则将替换为问号。

  3. 引用文件时,例如在 is_file 或 file 中,如果您传入 UTF-8 文件名,则当名称包含任何两个字节或更多字符时,将找不到该文件。但是,如果 UTF-8 字符可在 ISO-8859-1 中表示, is_file(utf8_decode($filename)) 等将起作用。

In other words, PHP5 is not capable of addressing files with multi-byte characters in their names at all.

换句话说,PHP5 根本无法处理名称中包含多字节字符的文件。

If a UTF-8 URL with multibyte characters is requested and this corresponds directly to a file, PHP won't be able to open the file because it cannot address it.

如果请求带有多字节字符的 UTF-8 URL 并且这直接对应于一个文件,PHP 将无法打开该文件,因为它无法对其进行寻址。

If you simply want pretty URLs in your language the suggestion of using mod_rewrite seems like a good one.

如果您只是想要在您的语言中使用漂亮的 URL,那么使用 mod_rewrite 的建议似乎是一个不错的建议。

But if you are storing and retrieving files uploaded and downloaded by users, this problem has to be resolved. One way is to use an arbitrary (non UTF-8) file name, such as an incrementing number, on the server and index the files in a database or XML file or some such. Another way is to store the files in the database itself as a BLOB. Another way (which is perhaps easier to see what is going on, and not subject to problems if your index gets corrupted) is to encode the filenames yourself - a good technique is to urlencode (sic) all your incoming filenames when storing on the server disk and urldecode them before setting the filename in the mime header for the download. All even vaguely unusual characters (except %) are then encoded as %nn and so any problems with spaces in file names, cross platform support and pattern matching are largely avoided.

但是如果你要存储和检索用户上传和下载的文件,这个问题就必须解决。一种方法是在服务器上使用任意(非 UTF-8)文件名,例如递增的数字,并在数据库或 XML 文件等中为文件编制索引。另一种方法是将文件作为 BLOB 存储在数据库本身中。另一种方法(这可能更容易看到发生了什么,并且在索引损坏时不会出现问题)是自己对文件名进行编码 - 一个很好的技术是在存储在服务器上时对所有传入的文件名进行 urlencode (sic)在下载的 mime 标头中设置文件名之前,请先对它们进行磁盘和 urldecode。所有甚至模糊不寻常的字符(% 除外)都被编码为 %nn,因此文件名中的任何空格问题,

回答by thomasrutter

  • I know for a fact PHP itself canwork with Unicode URLs, because I have tried using Unicode page names in MediaWiki (PHP-based, also runs WikiPedia) and it does work. Eg, URLs such as /index.php/Page_name?. So PHP can handle it. But it may be a problem with Apache finding a file where the source file has a UTF-8 name.

  • The PHP.ini setting for character encoding should not be affecting this; it is the job of the web server to find a specific resource and then call PHP once it's determined to be a PHP file. It will mean that the web server, and the underlying file system itself, have to be able to deal with UTF-8 filenames.

  • Does it work without the mod_rewrite rule? Ie, if you disable the rewrite engine with RewriteEngine off and then request va.in/utf_dir/utf_file.php? If so, then it may be a mod_rewrite config issue or a problem with the rule.

  • Unicode in URLs may not be properly supported in some browsers when you just type an address in, such as older browsers. Older browsers may skip the UTF-8 encoding step. This should not prevent it from working if you are following a link on a page, where that page is UTF-8 encoded, though.

  • 我知道 PHP 本身可以使用 Unicode URL,因为我曾尝试在 MediaWiki(基于 PHP,也运行 WikiPedia)中使用 Unicode 页面名称并且它确实有效。例如,诸如 /index.php/Page_name? 之类的 URL。所以PHP可以处理它。但是 Apache 查找源文件具有 UTF-8 名称的文件可能会出现问题。

  • 字符编码的 PHP.ini 设置不应影响此;Web 服务器的工作是查找特定资源,然后在确定它是 PHP 文件后调用 PHP。这意味着 Web 服务器和底层文件系统本身必须能够处理 UTF-8 文件名。

  • 没有 mod_rewrite 规则它可以工作吗?即,如果在关闭 RewriteEngine 的情况下禁用重写引擎,然后请求 va.in/utf_dir/utf_file.php?如果是这样,则可能是 mod_rewrite 配置问题或规则问题。

  • 当您只输入地址时,某些浏览器可能无法正确支持 URL 中的 Unicode,例如较旧的浏览器。较旧的浏览器可能会跳过 UTF-8 编码步骤。如果您正在访问页面上的链接,但该页面是 UTF-8 编码的,这不应阻止它工作。

回答by Fire Crow

Just because the character set is UTF-8 doesn't mean it supports all the higher characters of Unicode.

仅仅因为字符集是 UTF-8 并不意味着它支持 Unicode 的所有更高的字符。

Unicode support is one of the major additions coming in PHP 6 and PHP 5 is nutorious for lacking unicode support.

Unicode 支持是 PHP 6 中的主要新增功能之一,而 PHP 5 因缺乏 Unicode 支持而臭名昭著。

If your PHP script is generating the link it may be a different issue than if apache is interpreting the url directly and redirecting it.

如果您的 PHP 脚本生成链接,则与 apache 直接解释 url 并重定向它可能是不同的问题。

回答by Tristanisginger

No. PHP filenames must be in ASCII, it does not matter how you set up your server PHP5 can't cope so we wait for PHP 6. Within a PHP script you can handle utf-8 filename/url using utf8_decode. You can use a .htaccess and SQL to get around a lot of issues but there is no way to run a unicode filename.

不。PHP 文件名必须是 ASCII,不管你如何设置你的服务器 PHP5 无法应付,所以我们等待 PHP 6。在 PHP 脚本中,你可以使用 utf8_decode 处理 utf-8 文件名/url。您可以使用 .htaccess 和 SQL 来解决很多问题,但无法运行 unicode 文件名。

David Earl's answer is correct.

大卫厄尔的回答是正确的。

回答by Vitalicus

Use "wfio://" for copy write,e.t.c.

使用“wfio://”进行复制写入等

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

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

For folder:

对于文件夹:

.htaccess:

.htaccess:

php_value auto_prepend_file C:/fix.php

php_value auto_prepend_file C:/fix.php

fix.php:

修复.php:

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

But better for php use Linux OS

但更好的 php 使用 Linux 操作系统