PHP 5.3 存在的两个奇怪的错误,盼高手解答!

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 '<br/>';

$utf8Dir = '/var/www/html/a小猫b.txt';
echo basename($utf8Dir); echo '<br/>';

$utf8Dir = '/var/www/html/ab.txt';
echo basename($utf8Dir); echo '<br/>';

使用浏览器访问,页面显示如下:

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 如何应对

由于只发现了问题,而没找到产生问题的真正原因,所以无法直接解决它。我的应对措施是,避免使用这两个函数,需要其功能时,自己写一个类似的函数即可。
下面是我写的一个简单的分析文件路径的函数:

 // 计算目录名、文件名等
    public function GetPathInfo($fp)
    {
        $fi = array(); // [0]目录名部分(不包含最后的/), [1] 文件名 [2] 扩展名
        $lastSlash = strrpos($fp, '/');
        if($lastSlash === false){ // 没有目录部分
            $fi[0] = '';
            $filename = $fp;
        }else{
            $fi[0] = substr($fp, 0, $lastSlash);
            $filename = substr($fp, $lastSlash+1);
        }
        // 分离 abc.txt 中的abc 和 txt
        $lastPoint = strrpos($filename, '.');
        if($lastPoint === false){ // 没有扩展名
            $fi[1] = $filename;
            $fi[2] = '';
        }else{
            $fi[1] = substr($filename, 0, $lastPoint);
            $fi[2] = substr($filename, $lastPoint+1);
        }
        return $fi;
    }


你可能感兴趣的:(PHP,basename)