更新:
准备一份bug报告给那些让PHP 7成为可能的人,我再次修改了我的研究,并试图把它简化成几行简单的代码。在进行此操作时,我发现PHP本身并不是问题的原因。等我做完我会在这里分享我的结果。只是为了让你知道,而且不可能浪费你的时间什么的:)
概要: PHP7现在似乎能够编写UTF-8文件名,但无法访问它们?。
序言:我在这里读到了大约10-15篇涉及这个主题的文章,但它们并没有帮助我解决这个问题,而且它们都比PHP7版本更古老。在我看来,这可能是一个新的问题,我不知道它是否可能是一个错误。我花了很多时间尝试对字符串进行en/解码,并试图找到一种使其工作的方法,但没有结果。
大家好,来自德国的问候(在这里插入害羞而不是我的母语),我希望你能帮助我解决这个我遇到的新现象。在PHP 7中,它似乎是“新的”。
我认为大多数在Windows系统上使用PHP的人都非常熟悉文件名的问题,以及管理对具有非ASCII文件名(或windows-1252或任何系统代码页)的文件的访问的PHP透明包装器。
我不太清楚该如何处理这个问题,正如你所看到的,我在作题方面经验不足,所以请不要马上把我的头扯下来。是的,我会努力保持简短。我们开始:
第一个症状:在更新到PHP7之后,我有时会遇到访问由我的软件生成的文件的问题。有时它像往常一样工作,有时不起作用。我发现不同之处在于,PHP7现在似乎能够编写UTF-8文件名,但无法使用这些名称访问文件。
在两个独立的“相同”系统(仅在PHP版本中不同)上生成上述文件之后,硬盘上的文件就是这样命名的:
PHP5.5: Lokaltest_KG_æ¼¢å—_汉å—_Krümhold-DEZ1604-140081-complete.zip
PHP 7: Lokaltest_KG_漢字_汉字_Krümhold 1604-140081-完备.PHP
出色的是,PHP 7能够在HDD上编写unicode文件名,而UTF-16则可以在windows afaik上使用。现在的缺点是,当我尝试访问这些文件时,例如使用is_file(),PHP5.5是有效的,但是PHP7却不行。
考虑一下这个代码片段(注意:我“黑掉”了这个函数,因为它是最简单的方式,不是为此目的编写的)。在生成zip文件后调用此函数,获取客户的名称和其他值以确定正确的名称。从数据库里出来的。PHP的数据库和内部编码都是UTF-8.clearstatcache本身并不是必要的,但我加入它是为了让事情变得更清楚。:所有发生的事情都是用PHP7完成的,没有其他实体负责创建zip文件。准确地说,这是用class ZipArchive完成的。实际上,即使是压缩存档也无关紧要,关键是文件名和文件内容都是由PHP7成功创建的。
public static function downloadFileAsStream( $file )
{
clearstatcache();
print $file . "<br/>";
var_dump(is_file($file));
die();
} 产出如下:
D:/htdocs/otm/.data/_tmp/Lokaltest_KG_漢字_汉字_Krümhold-DEZ1604-140081-complete.zip
bool(false) 因此,PHP7能够生成文件--它们确实存在于硬盘上,并且是合法的、可访问的和所有的--但是无法访问它们。is_file不是唯一失败的函数,例如file_exists()也会失败。
通过一个编码转换的小实验,让您体验一下我尝试过的一些东西:
public static function downloadFileAsStream( $file )
{
clearstatcache();
print $file . "<br/>";
print mb_detect_encoding($file, 'ASCII,UTF-16,windows-1252,UTF-8', false) . "<br/>";
print mb_detect_encoding($file, 'ASCII,UTF-16,windows-1252,UTF-8', true) . "<br/>";
if (($detectedEncoding = mb_detect_encoding($file, 'ASCII,UTF-16,windows-1252,UTF-8', true)) != 'windows-1252')
{
$file = mb_convert_encoding($file, 'UTF-16', $detectedEncoding);
}
print $file . "<br/>";
var_dump(is_file($file));
die();
} 产出如下:
D:/htdocs/otm/.data/_tmp/Lokaltest_KG_漢字_汉字_Krümhold-DEZ1604-140081-complete.zip
UTF-8
UTF-8
D:/htdocs/otm/.data/_tmp/Lokaltest_KG_o"[W_lI[W_Kr�mhold-DEZ1604-140081-complete.zip
NULL 因此,从UTF-8 (数据库/内部编码)转换到UTF-16 (windows文件系统)似乎也不起作用。
我在这里束手无策,不幸的是,这个问题对我们来说非常重要,因为我们不能用这个问题来更新我们的系统。我希望有人能对这件事有所了解。不好意思,太长了,我不知道我能不能把我的观点说清楚。
加法:
$file = utf8_decode($file);
var_dump(is_file($file));
die();传递假的文件名与日本字母。当我更改用于创建文件名的输入,使文件名现在为Lokaltest_KG_Krümhold-DEZ1604-140081-complete.zip时,上面的代码将传递真。那么,utf8_decode只对一小部分unicode,德国货币有帮助吗?
发布于 2016-05-11 16:48:46
在这里回答我自己的问题:真正的坏男孩是组件ZipArchive,它用错误编码的文件名创建文件。我写了一个有希望有帮助的bug报告:https://bugs.php.net/bug.php?id=72200
考虑一下这个简短的脚本:
print "php default_charset: ".ini_get('default_charset')."\n"; // just 4 info (UTF-8)
$filename = "bugtest_müller-lüdenscheid.zip"; // just an example
$filename = utf8_encode($filename); // simulating my database delivering utf8-string
$zip = new ZipArchive();
if( $zip->open($filename, ZipArchive::CREATE | ZipArchive::OVERWRITE) === true )
{
$zip->addFile('bugtest.php', 'bugtest.php'); // copy of script file itself
$zip->close();
}
var_dump( is_file($filename) ); // delivers ?产出:
output PHP 5.5.35:
php default_charset: UTF-8
bool(true)
output PHP 7.0.6:
php default_charset: UTF-8
bool(false)https://stackoverflow.com/questions/37138463
复制相似问题