我已经获得了这段代码
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语句包含我正在检查的对象,这个if语句也会运行,而foreach就在这里,如果要证明这一点,我返回的数组包含这个 message ="文件夹F不包含X此文件夹中的所有文件X Y Z" 只是表明,contains函数返回一个不正确的值,因为X和X是相同的。
我希望我能够详细解释这一点。
有谁知道这可能是什么原因?
感谢。
答案 0 :(得分:0)
与Doctrine一样,因为他们的开发人员非常害怕开发人员友好,这个答案只是我所拥有的理论,也许有人可以纠正,证明或反驳我将要撰写的内容。
我本应该提到它,但不认为它实际上很重要,因为这些操作发生在此检查之后,但这段代码是“移动”功能的一部分,它需要两个文件夹和一个文件,并删除从一个文件夹中的文件并添加到另一个文件夹。
说明:
我认为造成这种情况的原因,是Doctrine与PHP optimzer相结合的非常奇怪的行为,如果存在这样的话。
Doctrine会在数据库操作开始时打开一个事务,并在发生错误时将其回滚,但在运行flush()时将其刷新到数据库。这听起来很合理,但这似乎不适用于删除,或者更适用于使用ArrayCollection的函数,因为ArrayCollections是直接映射到表,当你对它运行removeElement函数时,它立即,没有刷新,删除它来自数据库,没有问题,在我的“移动”功能中,这意味着如果我在执行所有操作后进行刷新,它将首先删除所有文件,然后在flush()函数后添加它们被调用,但如果发生错误,(我真的不记得了)我认为所有文件都将被删除...
我不知道这是不是真的,但我很确定PHP有某种优化器,它可能会移动代码并以更优化的方式运行它,然后程序员将其写入。
理论:
因为Doctrine立即删除文件而没有刷新操作,并且如果PHP移动代码,可能会发生,检查文件是否在该文件夹中的我的代码是在文件已经从数据库中删除后运行的,但是文件夹对象仍然包含文件!
解决方案:
您可以将ADD / REMOVE组合转换为合并操作,以便刚刚修改对象(File),或者可以将“contains”函数移动到移动函数之外,这样它就不会受到影响通过假定的代码顺序操作(实际上对我有效)。
希望这有助于某人。