ArrayCollection (Doctrine)包含返回错误结果的函数


ArrayCollection ( Doctrine ) contains function returns incorrect results

我已经有了这段代码

if(!$from->getFiles()->contains($proxy))
 {
    $return = "";
    foreach($from->getFiles() as $file)
    {
        $return .= $file->getFilename() . " --- ";
    }
    return array('type' => 'error', 'message' => 'Folder 
'.$from->getName().' does not contain '.$proxy->getFilename(). ' 
All files from this folder '. $return);
 }

很抱歉格式不好,这只是一条调试信息。

$from是一个文件夹模型。

与getFiles()(它返回的变量)的关系如下

/**
 * @ORM'ManyToMany(targetEntity="FileProxy", fetch="EXTRA_LAZY")
 * @ORM'JoinTable(name="file_system_folders_files",
 *      joinColumns={@ORM'JoinColumn(name="file_system_folder_id", referencedColumnName="id")},
 *      inverseJoinColumns={@ORM'JoinColumn(name="proxy_id", referencedColumnName="id", unique=true)})
 */
protected $files;

getFiles()是一个函数,它返回$files,包含在该文件夹中,它返回和ArrayCollection。

/**
 * Get files
 *
 * @return 'Doctrine'Common'Collections'Collection 
 */
public function getFiles()
{        
    return $this->files;
}

$proxy是一个FileProxy类型的对象,它是一个文件模型。

问题是,这个if语句运行,即使它包含我正在检查的对象,foreach在这个if中证明,我返回的数组包含这个message = "文件夹F不包含X文件夹X Y Z中的所有文件"这只是表明,contains函数返回一个不正确的值,因为X和X是相同的。

我希望我解释得足够详细。

有人知道这可能是什么原因吗?

谢谢。

和Doctrine一样,因为他们的开发者非常不擅长对开发者友好,所以这个答案只是我的一个理论,也许有人可以纠正、证明或反驳我将要写的东西。

我应该提到它,但不认为它实际上是重要的,因为这些操作发生在这个检查之后,但这段代码是"移动"函数的一部分,它需要两个文件夹和一个文件,并从一个文件夹中删除文件并添加到另一个文件夹。


解释:

我认为造成这种情况的原因,是Doctrine结合PHP优化器的非常奇怪的行为,如果这样的事情存在的话。

  1. Doctrine在数据库操作开始时打开一个事务,在发生错误时回滚它,但在运行flush()时将其刷新到数据库。这听起来很合理,但这似乎不适用于删除,或者更确切地说,对于与ArrayCollection一起工作的函数,因为ArrayCollections是直接映射到表的,当您在其上运行removeElement函数时,它立即,无需冲洗,将其从数据库中删除,没有问题,这在像我这样的"移动"函数中,意味着如果我在执行所有操作后冲洗,它将首先删除所有文件,然后添加它们一旦flush()函数被调用,但如果发生错误,(我真的不记得)我认为所有的文件将保持删除…

  2. 我不知道这是不是真的,但我很确定PHP有某种优化器,它可能会移动代码并以更优化的方式运行,然后程序员写它。


理论:

因为Doctrine立即删除文件,没有flush操作,如果PHP移动代码,它可能会发生,我的代码,检查文件是否在文件夹中运行后,文件已经从数据库中删除,但文件夹对象仍然包含文件!


解决方案:

您可以将ADD/REMOVE组合转换为合并操作,以便对象(文件)只是被修改,或者您可以将"包含"函数移到移动函数之外,以便它不受假定的代码顺序操作(实际上对我有效)的影响。