如何在PHP中打开名称中包含unicode字符的文件?

时间:2009-06-10 19:23:06

标签: php string unicode

例如我有一个像这样的文件名 - проба.xml,我无法从PHP脚本中打开它。

如果我将php脚本设置为utf-8,那么脚本中的所有文本都是utf-8,因此当我将其传递给file_get_contents时:

$fname = "проба.xml";
file_get_contents($fname);

我收到文件不存在的错误。原因是在Windows(XP)中,所有带有非拉丁字符的文件名都是unicode(UTF-16)。好的,所以我尝试了这个:

$fname = "проба.xml";
$res = mb_convert_encoding($fname,'UTF-8','UTF-16');
file_get_contents($res);

但错误仍然存​​在,因为file_get_contents无法接受unicode字符串......

有什么建议吗?

3 个答案:

答案 0 :(得分:11)

更新(7月13日&17; 17)

虽然文档似乎没有提及它,但PHP 7.0及更高版本最终支持Windows上的Unicode文件名。 PHP的文件系统API根据default_charset接受并返回文件名,默认情况下为UTF-8

请参阅此处的错误修正:https://github.com/php/php-src/commit/3d3f11ede4cc7c83d64cc5edaae7c29ce9c6986f


更新(1月29日' 15)

如果您有权访问PHP扩展目录,可以尝试在https://github.com/kenjiuno/php-wfio安装php-wfio.dll,并通过wfio://协议引用文件。

file_get_contents("wfio://你好.xml");

原始答案

Windows上的PHP使用Legacy" ANSI API"专门用于本地文件访问,这意味着PHP使用系统区域设置而不是Unicode。

要访问文件名包含Unicode的文件,必须将文件名转换为当前系统区域设置的指定编码。 如果文件名包含在指定编码中无法表示的字符,那么您将失去运气 (更新:请参阅上面的解决方案部分)scandir将为这些文件返回乱码并将字符串传回fopen,等效项将失败。

要找到要使用的正确编码,您可以通过调用<?=setlocale(LC_TYPE,0)?>并查找代码页标识符.之后的数字)来获取系统区域设置在MSDN文章https://msdn.microsoft.com/en-us/library/dd317756(VS.85).aspx

例如,如果函数返回Chinese (Traditional)_HKG.950,则表示950代码页正在使用,文件名应转换为big-5编码。在这种情况下,如果您的文件以UTF-8保存(最好没有BOM),您的代码必须如下所示:

$fname = iconv('UTF-8','big-5',"你好.xml");
file_get_contents($fname);

或如果直接将文件另存为Big-5:

$fname = "你好.xml";
file_get_contents($fname);

答案 1 :(得分:0)

你可以尝试:

  • 使用opendir和readdir
  • 从目录列表中获取文件名的字符串
  • 将该字符串传递给file_get _contents以查看是否可行,或
  • 尝试使用fopen,fread和fclose
  • 获取文件的内容

希望这有帮助!

答案 2 :(得分:0)

目前为止的结论是:

  1. 除非源文件名为unicode,否则PHP 5无法使用unicode字符打开文件名。
  2. PHP 5(至少在Windows XP上)无法以unicode处理PHP源代码。
  3. 因此,这个结论在PHP 5中无法实现。