我之前开始探索这个问题here。这是真正的问题,也是一个建议的解决方案:
ASCII字符值介于32和255之间的文件名对utf8_encode()造成问题。具体来说,它没有正确处理126和160之间的字符值。虽然可以将具有这些字符名称的文件名写入数据库,但将这些文件名传递给PHP代码中的函数会产生错误消息,指出无法找到该文件等。
我在尝试将带有违规字符的文件名传递给getimagesize()时发现了这一点。
utf8_encode所需要的是一个过滤器,用于排除包含在126和160之间的值的转换,同时包括所有其他字符(或用户的任何字符,字符或字符范围)的转换;由于提供的原因,我的是规定的范围。
我设计的解决方案需要下面列出的两个函数及其应用程序:
// With thanks to Mark Baker for this function, posted elsewhere on StackOverflow
function _unichr($o) {
if (function_exists('mb_convert_encoding')) {
return mb_convert_encoding('&#'.intval($o).';', 'UTF-8', 'HTML-ENTITIES');
} else {
return chr(intval($o));
}
}
// For each character where value is inclusively between 126 and 160,
// write out the _unichr of the character, else write out the UTF8_encode of the character
function smart_utf8_encode($source) {
$text_array = str_split($source, 1);
$new_string = '';
foreach ($text_array as $character) {
$value = ord($character);
if ((126 <= $value) && ($value <= 160)) {
$new_string .= _unichr($character);
} else {
$new_string .= utf8_encode($character);
}
}
return $new_string;
}
$file_name = "abcdefghijklmnopqrstuvxyz~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”–—˜™š›œžŸ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ.jpg";
// This MUST be done first:
$file_name = iconv('UTF-8', 'WINDOWS-1252', $file_name);
// Next, smart_utf8_encode the variable (from encoding.inc.php):
$file_name = smart_utf8_encode($file_name);
// Now the file name may be passed to getimagesize(), etc.
$getimagesize = getimagesize($file_name);
如果只有PHP7(编号中跳过6,是吗?)会在utf8_encode()上包含一个过滤器来排除某些字符值,那么这些都不是必需的。