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

Ale*_*lex 10 php utf-8 character-encoding

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

  • test.pdf:工作正常
  • tést.pdf:不起作用(注意é - 急性重音 - 在文件名中)

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

$file = htmlentities($file,ENT_QUOTES,'UTF-8');
Run Code Online (Sandbox Code Playgroud)

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

如果我打电话:$ file = htmlentities($ file,ENT_IGNORE,'UTF-8'); 急性特征刚刚被删除(因此tést.pdf变为tst.pdf)

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

因此,我非常善于在这里找到解决方案.欢迎任何帮助.

供参考:

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

Jas*_*wer 15

我最好的猜测是文件名本身不使用UTF-8.或者至少scandir()不是那样捡起来的.

也许mb_detect_encoding()可以解决一些问题?

var_dump(mb_detect_encoding($filename));
Run Code Online (Sandbox Code Playgroud)

如果没有,尝试猜测编码(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'));
Run Code Online (Sandbox Code Playgroud)

或使用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));
Run Code Online (Sandbox Code Playgroud)

然后当你弄清楚实际使用了哪种编码时,你的代码应该看起来像这样(假设CP1252):

$filename = htmlentities(mb_convert_encoding($filename, 'UTF-8', 'Windows-1252'), ENT_QUOTES, 'UTF-8');
Run Code Online (Sandbox Code Playgroud)