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

PHP编码转换为Windows-1252,同时保持UTF-8兼容性,php,encoding,utf-8,character-encoding,windows-1252,Php,Encoding,Utf 8,Character Encoding,Windows 1252,我需要将上传的文件名转换为未知编码的Windows-1252,同时保持UTF-8兼容性 当我将这些文件传递给一个我没有任何影响的控制器时,这些文件必须是Windows-1252编码的。然后,这个控制器再次生成一个有效文件名列表,这些文件名通过MySQL存储到数据库中,因此我需要UTF-8兼容性。传递给控制器的文件名和写入数据库的文件名必须匹配。到目前为止还不错 在一些罕见的情况下,当转换为Windows-1252(如te characterï)时,该字符会转换为UTF-8中的无效字符。MySQL

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

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

在一些罕见的情况下,当转换为Windows-1252(如te characterï)时,该字符会转换为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而不丢失有效的特殊字符,请告诉我


非常感谢您的帮助。提前谢谢你

不能让字符串同时为Windows-1252和UTF-8。字符集包含的前128个字符是相同的,例如基本拉丁字母表,但是当它超出这个范围时,就像Umlauts一样,它要么是一个,要么是另一个。他们在UTF-8中的代码点与在Windows-1252中的不同。

我认为主要的问题是它没有完全按照您认为的那样执行。它试图检测字符编码,但它是从相当有限的预定义编码列表中检测的。默认情况下,这些编码是由返回的编码。在我的计算机中,它们是:

ASCII码 UTF-8 因此,除非编译候选编码列表并将其提供给函数,否则此函数是完全无用的


此外,基本上没有可靠的方法来猜测任意输入字符串的编码,即使您仅限于编码的一小部分。在您的情况下,Windows-1252与ISO-8859-1和ISO-8859-15非常接近,除了目视检查关键字符(如€或€)之外,您无法将它们区分开来。请在文件系统中保留ASCII-如果您需要在文件名中保留ASCII以外的字符,则有 可用于表示unicode字符的方案,同时保持ASCII

例如,百分比编码:

txt%C3%A4%C3%B6%C3%BC%C3%84%C3%96%C3%9C.txt

当然,这会很快达到文件名限制,而且不是很理想

怎么样

äöü196;äÜ.txt xn-4caa7cb2ac.txt