我已经有了这段代码
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优化器的非常奇怪的行为,如果这样的事情存在的话。
-
Doctrine在数据库操作开始时打开一个事务,在发生错误时回滚它,但在运行flush()时将其刷新到数据库。这听起来很合理,但这似乎不适用于删除,或者更确切地说,对于与ArrayCollection一起工作的函数,因为ArrayCollections是直接映射到表的,当您在其上运行removeElement函数时,它立即,无需冲洗,将其从数据库中删除,没有问题,这在像我这样的"移动"函数中,意味着如果我在执行所有操作后冲洗,它将首先删除所有文件,然后添加它们一旦flush()函数被调用,但如果发生错误,(我真的不记得)我认为所有的文件将保持删除…
-
我不知道这是不是真的,但我很确定PHP有某种优化器,它可能会移动代码并以更优化的方式运行,然后程序员写它。
理论:
因为Doctrine立即删除文件,没有flush操作,如果PHP移动代码,它可能会发生,我的代码,检查文件是否在文件夹中运行后,文件已经从数据库中删除,但文件夹对象仍然包含文件!
解决方案:
您可以将ADD/REMOVE组合转换为合并操作,以便对象(文件)只是被修改,或者您可以将"包含"函数移到移动函数之外,以便它不受假定的代码顺序操作(实际上对我有效)的影响。