我想访问一个名称中包含UTF-8字符的PHP文件.
该文件中没有BOM.它只包含一个显示一些unicode字符的echo语句.
从浏览器访问PHP页面(FireFox 3.0.8,IE7)会导致HTTP错误500.
Apache日志中有两个条目(文件是/க.php;字母க是复合的,对应于下面日志中的字符\ xe0\xae\x95):
[2009年4月4日星期六09:30:25] [错误] [客户端127.0.0.1] PHP警告:未知:无法打开流:第0行的"未知"中没有此类文件或目录
[Sat Apr 04 09:30:25 2009] [错误] [客户端127.0.0.1] PHP致命错误:未知:未能打开所需的'D:/ va/ROOT /\xe0\xae\x95.php'(include_path ='在第0行的Unknown中有.; C:\ php5\pear')
当文件和目录名称为英语时,同一页面有效.在相同的设置中,使用SSI对这些页面没有问题.
编辑
删除了网址重写的信息,因为它似乎不是一个因素.
删除mod_rewrite时,PHP文件仍然无效.如果文件重命名为非UTF名称,则工作.但是,shtml甚至可以在文件和/或路径名中使用UTF字符.
我遇到了同样的问题并做了一些研究并得出以下结论.这适用于Windows上的php5; 在其他平台上可能是这样,但我没有检查过.
所有php文件系统函数(dir,is_dir,is_file,file,filemtime,filesize,file_exists等)只接受并返回ISO-8859-1中的文件名,而不管程序或ini文件中设置的default_charset如何.
如果文件名包含unicode字符dir-> read将返回相应的ISO-8859-1字符(如果有),否则它将替换问号.
当引用文件时,例如在is_file或文件中,如果传入UTF-8文件名,则当名称包含任何两个字节或更多字符时,将找不到该文件.但是,is_file(utf8_decode($ filename))等将起作用,提供ISO-8859-1中可表示的UTF-8字符.
换句话说,PHP5根本无法寻址名称中包含多字节字符的文件.
如果请求具有多字节字符的UTF-8 URL并且这直接对应于文件,则PHP将无法打开该文件,因为它无法解决该问题.
如果您只是想要使用您的语言中的漂亮网址,那么使用mod_rewrite的建议就好了.
但是,如果要存储和检索用户上载和下载的文件,则必须解决此问题.一种方法是在服务器上使用任意(非UTF-8)文件名,例如递增数,并索引数据库或XML文件中的文件或某些文件.另一种方法是将文件作为BLOB存储在数据库中.另一种方式(可能更容易看到正在发生的事情,并且如果你的索引被破坏而不会出现问题)是自己编码文件名 - 一种好的技巧是在存储在服务器上时对你的所有传入文件名进行urlencode(sic)在下载的mime标头中设置文件名之前,磁盘和url会对它们进行编码.所有甚至模糊不寻常的字符(%除外)都被编码为%nn,因此在很大程度上避免了文件名,跨平台支持和模式匹配中的空格问题.
我知道PHP本身可以使用Unicode URL,因为我尝试在MediaWiki中使用Unicode页面名称(基于PHP,也运行WikiPedia),它确实有效.例如,诸如/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编码的.