PHP编码转换为Windows-1252,同时保持UTF-8兼容性

时间:2013-03-15 10:28:23

标签: php encoding utf-8 character-encoding windows-1252

我需要将带有未知编码的上传文件名转换为Windows-1252,同时保持UTF-8兼容性。

当我将这些文件传递给控制器​​(我没有任何影响)时,文件必须是Windows-1252编码的。然后,该控制器再次生成通过MySQL存储到数据库中的有效文件(名称)列表 - 因此我需要UTF-8兼容性。传递给控制器​​的文件名和写入数据库的文件名必须匹配。到目前为止一切都很好。

在极少数情况下,转换为“Windows-1252”(与te字符“ï”相似)时,该字符将转换为UTF-8中无效的字符。然后MySQL删除那些无效字符 - 因此磁盘上的文件名和存储到数据库的文件名不再匹配。这种转换有时会失败,只需简单的重新编码即可实现:

$sEncoding       = mb_detect_encoding($sOriginalFilename);
$sTargetFilename = iconv($sEncoding, "Windows-1252//IGNORE", $sOriginalFilename);

为了防止转换生成无效字符,我再次可以从重新编码的字符串中删除所有无效的UTF-8字符:

ini_set('mbstring.substitute_character', "none");
$sEncoding       = mb_detect_encoding($sOriginalFilename);
$sTargetFilename = iconv($sEncoding, "Windows-1252//TRANSLIT", $sOriginalFilename);
$sTargetFilename = mb_convert_encoding($sTargetFilename, 'UTF-8', 'Windows-1252');

但是这将完全删除/重新编码字符串中剩余的任何特殊字符。例如,我失去了所有“äöüÄÖÜ”等,这在德语中非常规律。

如果你知道一种更简洁的Windows-1252编码方式(不会丢失有效的特殊字符),请告诉我。

非常感谢任何帮助。提前谢谢!

3 个答案:

答案 0 :(得分:3)

您不能同时将字符串设置为Windows-1252和UTF-8。前128个字符的字符集是相同的(它们包含例如基本的拉丁字母),但是当它超出该字符集时(如同变形金刚),它可以是一个或另一个。它们在UTF-8中的代码点与在Windows-1252中的代码点不同。

答案 1 :(得分:2)

我认为主要问题是mb_detect_encoding()并不完全符合您的想法。它试图检测字符编码,但它是从一个相当有限的预定义编码列表中完成的。默认情况下,这些编码是mb_detect_order()返回的编码。在我的电脑里,他们是:

  • ASCII
  • UTF-8

所以这个函数完全没用,除非你负责编译候选编码列表并用它来提供函数。

此外,基本上没有可靠的方法来猜测任意输入字符串的编码,即使您将自己局限于一小部分编码。在您的情况下,Windows-1252非常接近ISO-8859-1ISO-8859-15,除了目视检查¤或€等关键字符外,您无法区分它们。

答案 2 :(得分:1)

在文件系统中保持ASCII - 如果你需要在文件名中维持ASCII之外的字符,那么就有了 您可以使用的方案来表示unicode字符,同时保持ASCII。

例如,百分比编码:

äöüÄÖÜ.txt< - > %C3%A4%C3%B6%C3%BC%C3%84%C3%96%C3%9C.txt

当然,这会非常快速地达到文件名限制。

punycode怎么样?

äöüÄÖÜ.txt< - > xn--4caa7cb2ac.txt