1

在 OS-X(PHP5.2.11)上,我有一个文件:siësta.doc(以及其他数千个带有 Unicode 文件名的文件),我想将文件名转换为网络可消费格式(a-zA-Z0-9.)。如果我硬编码上面的文件名,我可以进行正确的转换:

<?php
  $file = 'siësta.doc';
  echo preg_replace("/[^a-zA-Z0-9.]/u", '_', $file);
  // Output: si_sta.doc
?>

但是如果我用 scandir 读取文件名,我会得到奇怪的转换:

<?php
  $files = scandir(DIRNAME);
  foreach ($files as $file) {
    echo preg_replace("/[^a-zA-Z0-9.]/u", '_', $file);
    // Output for the file above: sie_sta.doc
  }
?>

我试图检测编码,设置编码,用 iconv 函数转换它。我也尝试了 mb_ 功能。但情况更糟。我做错什么了?

提前致谢

4

3 回答 3

2

有趣的。经过一番研究,我发现 OSX 将文件名存储为“分解的 unicode”(参见http://developer.apple.com/mac/library/qa/qa2001/qa1173.html)。也就是说,“ë”表示为“e”+分叉符号(0xcc88)。

于 2010-03-15T14:15:35.643 回答
0

你试过utf8_encode吗?(至少在 Windows 上工作)

<?php
  $files = scandir(DIRNAME);
  foreach ($files as $file) {
    echo preg_replace("/[^a-zA-Z0-9.]/u", '_', utf8_encode($file));
    // Output for the file above: sie_sta.doc
  }
?>
于 2010-03-15T14:12:45.743 回答
0

问题是windows和php之间的通信。无法获得 unicode 文件名,因为它们依赖于非 unicode windows 应用程序语言。

最好的解决方案是执行 dir 命令并获取要处理的信息,但您必须通过 cmd 执行此操作,并获取 Windows 短名称:

chcp 65001
dir /x c:\test\ > myinfo.txt

它返回:

 El volumen de la unidad C es Windows8_OS
 El número de serie del volumen es: 14A3-025F

 Directorio de C:\test

22/12/2015  22:11    <DIR>                       .
22/12/2015  22:11    <DIR>                       ..
22/12/2015  22:12                 0              a.txt
22/12/2015  22:10    <DIR>                       English
22/12/2015  22:10    <DIR>          ESPAOL~1     Español
22/12/2015  22:11    <DIR>          8311~1       ру́сский язы́к
22/12/2015  22:10    <DIR>          _0B41~1      عربي ,عربى
22/12/2015  22:10    <DIR>          8F4C~1       北方話
               1 archivos              0 bytes
               7 dirs  839.672.786.944 bytes libres

然后,您可以阅读 myinfo.txt 以获取原始名称和 Windows 短名称之间的联系。

一些 PHP 函数适用于短名称,您可以构建和排列,就好像您需要显示它一样:

$array['short_name']= $original_name;

例如:is_dir, is_file 工作正常。但是,scandir或者也is_readable 因短名称而失败。使用这些函数的解决方案是递归地重新运行 dir 命令。

要从 txt 文件中获取信息,您可以使用正则表达式或 substr,丢弃前五行和后两行。例如:

for($k=6;$k<(count($array)-2);$k++) ...
于 2015-12-22T21:28:18.460 回答