代码之家  ›  专栏  ›  技术社区  ›  Darko Miletic

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

  •  8
  • Darko Miletic  · 技术社区  · 16 年前

    例如,我有一个这样的文件名-_____.xml,我无法从PHP脚本打开它。

    如果我将php脚本设置为utf-8格式,那么脚本中的所有文本都是utf-8格式,因此当我将其传递给文件“获取”内容时:

    $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);
    

    但是错误仍然存在,因为文件获取内容不能接受Unicode字符串…

    有什么建议吗?

    3 回复  |  直到 8 年前
        1
  •  9
  •   Henry    8 年前

    更新(2017年7月13日)

    尽管文档似乎没有提到它,但php 7.0及更高版本最终在Windows上支持Unicode文件名。PHP的文件系统API根据 default_charset ,这就是 UTF-8 默认情况下。

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


    更新(2015年1月29日)

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

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

    原始答案

    Windows上的PHP使用传统的“ansi apis”专门用于本地文件访问,这意味着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);
    
        2
  •  0
  •   ylebre    16 年前

    你可以试试:

    • 使用opendir和readdir从目录列表中获取文件名的字符串
    • 将该字符串传递到文件获取内容以查看是否有效,或者
    • 尝试使用fopen、fread和fclose获取文件内容

    希望这有帮助!

        3
  •  0
  •   Darko Miletic    16 年前

    以下是迄今为止的结论:

    1. 除非源文件名为unicode,否则php 5无法打开具有unicode字符的文件名。
    2. php 5(至少在WindowsXP上)无法用Unicode处理php源代码。

    因此,这个结论在PHP5中是不可行的。