php – 比较SplFileInfo对象始终返回true

我几乎让自己相信这只是漏洞抽象,让人头疼,但我在提交错误报告之前想到了我可能会调查Stack Overflow以获得更有见地的答案……

我正在用PHP编写一个类以帮助自动加载.我讨厌使用Zend框架使用的荒谬的,面向路径的类名,所以我改为编写一个类来创建一个对象,以递归方式遍历目录及其子目录,查找所有PHP源文件,并为类解析它们定义,然后缓存并重复使用,直到自动加载失败,这会提示对象更新其索引.

我喜欢尽可能使用内置的PHP类,因此对于索引路径,我使用了SplFileInfo类.

更新类索引所需的一些操作要求我搜索我的对象所持有的SplFileInfo对象数组,这是我在SplFileInfo对象上使用比较运算符时遇到的一些麻烦.

简单地说,搜索任何文件总是返回true.起初我对它感到有些困惑,但是我已经在两台机器上尝试了它并且让一个朋友尝试了它 – 同样的结果.看似无论如何,当您使用比较(==)运算符比较两个SplFileInfo对象时,它返回true,即使它们指向位于完全目录中的不同文件.我是否使用循环迭代数组中的每个元素并比较这种方式,使用in_array()或array_search(),它总是返回true并给我一个完全不同的文件的引用.

我进一步调整了一下,发现即使两个SplFileInfo对象指向完全相同的文件,并使用相同的路径字符串初始化,识别运算符(===)总是返回false.

对于我的代码,这意味着当我去更新类索引以查看是否有任何新文件时,即使文件是新文件,索引器对象也认为它已经知道该文件并继续前进.我通过比较路径名字符串使这个工作起作用,但是那种方法打败了使用SplFileInfo类的目的.

PHP手册说扩展开发人员可以重载对象的比较运算符,这就是为什么我假设SplFileInfo足够智能来解析相对路径并正确地将它与其他相对路径进行比较,例如./file和文件是相同的.事实证明,它只在那些实例中返回true,因为它在比较两个SplFileInfo对象时总是返回true!

这与我正在处理的代码无关.我尝试了一个带有一些新的SplFileInfo对象的临时源文件,并对它们进行了比较.无论对象是指向不同的文件,同一文件还是不存在的文件,它都返回true.

由于这不是PHP中对象的比较运算符的默认行为,因此在扩展中的类的定义中必须存在导致此问题的内容.

有没有人知道它为什么会这样,或有任何见解?

最佳答案 安德鲁,

我已经做了一些自己用SPL类进行实验,而且令人惊讶的是SplFileInfo并不是唯一展示这种行为的SPL类.例如,ArrayIterator也以同样的方式做出反应.我假设更多(如果不是全部)SPL类具有此行为.

虽然我没有回答为什么存在这种行为,但我确实针对您的具体情况采取了解决方法.你可能已经自己想出了这个,但我想我还是分享它:

class MyFileInfo extends SplFileInfo
{
    private $_realPath;

    public function __construct( $path )
    {
        parent::__construct( $path );
        $this->_realPath = $this->getRealPath();
    }

}
点赞