PHP scandir()和htmlentities():字符集和/或特殊字符的问题


utf 8 - PHP scandir() and htmlentities(): issues with charset and/or special characters

我使用jqueryFileTree来显示服务器上的目录列表,其中包含指向该目录中文件的下载链接。最近我遇到了一个包含特殊字符的文件的问题:

  • test.pdf: works fine
  • t .pdf:不工作(注意文件名中的 -重音-)

在调试jqueryFileTree的php连接器时,我看到它正在对通过$_GET传递的目录进行scandir(),然后循环遍历目录的每个文件/dir。在将文件名解析为url之前,脚本似乎正确地对文件名执行了htmlentities()。问题似乎是这个htmlentities($file)调用只是返回一个空字符串,根据php文档,这可能是输入字符串包含给定编码内的无效代码单元的情况。然而,我尝试通过调用:

来隐式传递字符集。
$file = htmlentities($file,ENT_QUOTES,'UTF-8');

但是这也返回一个空字符串。

如果我调用:$file = htmlentities($file,ENT_IGNORE,'UTF-8');急号字符被省略了(所以tsamest .pdf变成了test .pdf)

当用xdebug调试我的php脚本时,我可以看到源字符串包含一个未知字符(看起来像这样)。

所以我在我的智慧在这里找到解决方案。欢迎任何帮助。

供参考:

  • 我的页面的字符集是UTF-8(在元数据中指定)
  • 文件存储在windows 2003文件服务器上,scandir()在UNC路径下执行(例如//fileserver/sharename/sourcedir)
  • 我的php.ini中的默认编码设置为UTF-8
  • web服务器&PHP 5.4.26在windows 2008 R2服务器上运行

我最好的猜测是文件名本身没有使用UTF-8。或者至少scandir()没有像那样拾取它。

也许mb_detect_encoding()能给我们一些启示?

var_dump(mb_detect_encoding($filename));

如果不是,尝试猜测编码(CP1252或ISO-8859-1将是我的第一个猜测)并将其转换为UTF-8,看看输出是否有效:

var_dump(mb_convert_encoding($filename, 'UTF-8', 'Windows-1252'));
var_dump(mb_convert_encoding($filename, 'UTF-8', 'ISO-8859-1'));
var_dump(mb_convert_encoding($filename, 'UTF-8', 'ISO-8859-15'));

或使用iconv():

var_dump(iconv('WINDOWS-1252', 'UTF-8', $filename));
var_dump(iconv('ISO-8859-1',   'UTF-8', $filename));
var_dump(iconv('ISO-8859-15',  'UTF-8', $filename));
然后,当您弄清楚实际使用的编码时,您的代码应该看起来像这样(假设是CP1252):

$filename = htmlentities(mb_convert_encoding($filename, 'UTF-8', 'Windows-1252'), ENT_QUOTES, 'UTF-8');