1 试验环境
CentOS 6 + PHP 5.3.3,2015年2月26日,已通过yum更新到最新状态。
2 错误描述2.1 basename()函数对UTF-8编码的路径返回错误结果。
这个非常容易验证,建立一个UTF-8编码的php源文件 test.php,内容如下:
<?php $utf8Dir = '/var/www/html/小猫b.txt';echo basename($utf8Dir); echo '
';$utf8Dir = '/var/www/html/a小猫b.txt';echo basename($utf8Dir); echo '
';$utf8Dir = '/var/www/html/ab.txt';echo basename($utf8Dir); echo '
';
使用浏览器访问,页面显示如下:
b.txt
a小猫b.txt
ab.txt
可见,如果名字不是以ASCII码开始,那么其中的汉字就会被丢弃,一直到遇到一个ASCII字符开始才不丢汉字。另外dirname()不存在这个问题。
2.2 ZipArchive::extractTo()也存在同样的问题。
如果.zip包里的文件不是纯ASCII码,那么同样的,文件中的汉字部分会被丢弃。然而文件还是被解压了,只是解压后的文件名字不对了。如果是全汉字的文件名,那么解压后文件名全部被丢弃,
结果只剩下一个.和扩展名部分,从而成了一个隐藏文件。
例如:小猫.txt解压后成为.txt。
个人感觉,此方法内部是调用了basename()这个有问题的函数,从而导致这个问题的发生。
2.3 奇怪之处
上面的两个问题,在本地执行php程序时,都不存在。也就是在PHP引擎所在主机上通过命令行 php test.php执行,则上述两个问题都不复存在。这到底是为什么呢?个人猜测basename()内部依赖于
某些环境变量,而通过网页访问访问时,这些变量设置不正确,从而导致问题发生。到底是什么原因,还请高手给予解答。。。(郁闷了一天了,希望有人能解释)
3 如何应对由于只发现了问题,而没找到产生问题的真正原因,所以无法直接解决它。我的应对措施是,避免使用这两个函数,需要其功能时,自己写一个类似的函数即可。