ArrayCollection(Doctrine)包含函数返回不正确的结果 [英] ArrayCollection ( Doctrine ) contains function returns incorrect results

查看:92
本文介绍了ArrayCollection(Doctrine)包含函数返回不正确的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这段代码

  if(!$ from-> getFiles() - >包含($ proxy))
{
$ return =;

foreach($ from-> getFiles()as $ file)
{
$ return。= $ file-> getFilename()。 ---;
}

返回数组('type'=>'error','message'=>'文件夹
'$ from-> getName()不包含'。$ proxy-> getFilename()。'
此文件夹中的所有文件。$ return);
}

我很抱歉格式不正确,但这只是一个调试信息。 / p>

$ 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()是一个函数,它返回$文件,该文件包含在该文件夹中,返回和ArrayCollection。

  / ** 
*获取文件
*
* @return \Doctrine\Common\Collections\Collection
* /
public function getFiles()
{
return $ this-> files;
}

$ proxy是FileProxy类型的对象,它会对文件建模。 p>

问题是,这个if语句运行,即使它包含我正在检查的对象,并且foreach是在这里如果证明,我的数组返回包含这个
message =文件夹F不包含X此文件夹XYZ中的所有文件
,它只显示,包含函数返回一个不正确的值,因为X和X是相同的。 p>

我希望我详细解释了这一点。



有谁知道这可能是什么原因? p>

谢谢。

解决方案

与Doctrine一样,因为他们的开发人员非常开发人员友善的答案很可怕,这个答案只是一个理论,也许有人可以纠正,证明或反驳我要写的内容。



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






说明:



我认为是什么原因如果这样的事情存在,那么Doc​​trine结合PHP优化器是非常奇怪的行为。


  1. 数据库操作启动,并在发生不良情况时将其回滚,但在运行flush()时将其刷新到数据库。这听起来非常合理,但这似乎对删除操作似乎不起作用,或者对于使用ArrayCollection的函数来说似乎不起作用,因为ArrayCollections是一个直接映射到表的函数,当您运行一个removeElement函数时,它将立即删除它从数据库中,没有问题,在Move功能像我的意思是,如果我在执行所有操作后刷新,它将首先删除所有文件,然后添加一次flush()函数被调用,但如果发生错误,(我真的不记得)我认为所有的文件将保持删除...


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







理论:


因为Doctrine立即删除文件,无需刷新操作,如果PHP移动代码,它c可能会发生,我的代码,检查文件是否在该文件夹中运行后文件已从数据库中删除,但文件夹对象STILL包含文件!






解决方案:



您可以将ADD / REMOVE组合转换为合并操作对象(File)刚刚被修改,或者你可以在移动函数之外移动contains函数,这样它不受假定的代码顺序操作(实际上对我有用)的影响。



希望这有助于某人。


I've got this piece of code

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);
 }

I'm sorry it's badly formatted, but it's just a debug message.

$from is a model of a folder.

the relation to getFiles() ( the variable it returns ) is this

/**
 * @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() is a function, that returns $files, that are contained in that folder, and it returns and ArrayCollection.

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

$proxy is an object of type FileProxy and it models a file.

The problem is, this if statement runs even if it contains the object that I'm checking, and the foreach is in this if to prove that, the array that I'm returning contains this message = " Folder F does not contain X All files from this folder X Y Z " which just shows, that the contains function returns an incorrect value, because X and X are the same.

I hope I explained this in enough detail.

Does anyone know what might be the cause of this ?

Thanks.

解决方案

As everything with Doctrine, because their developers are awfully awful at being developer friendly, this answer is just a theory I have, maybe someone could correct, prove, or disprove what I am about to write.

I should have probably mentioned it, but did not think it was actually important, because those operations happen after this check, but this code is a part of "Move" function, it takes two Folders and a File, and remove the File from one Folder and add to the other Folder.


Explanation:

What I think is the cause of this, is very bizarre behavior of Doctrine combined with PHP optimzer, if such a thing exists.

  1. Doctrine opens a transaction whenever a database operation starts, and rolls it back when something bad happens, but flushes it to the database when you run flush(). That sounds very reasonable, but that does not seem to work for deletes, or rather for functions that work with ArrayCollection, since ArrayCollections are a direct mapping to a table, when you run a removeElement function on it, it IMMEDIATELY, without flushing, removes it from the database, no questions asked, which in a "Move" function like mine, means that if I flush after performing all of the operations, it will first delete all of the files, and then add them once the flush() function is called, but if an error occures, ( I don't really remember ) I think all of the files will remain deleted ...

  2. I don't know if that is true, but I am pretty sure PHP has some kind of an optimizer, it probably moves code around and runs it in a more optimized way, then the programmer wrote it in.


Theory:

Because Doctrine deletes files immediately, without the flush operation, and if PHP moves code around, it could happen, that my code, that checks if the File is in that Folder is run AFTER the File has already been deleted from the database, but the Folder object STILL CONTAINS the Files!


Solution:

You could either transform the ADD/REMOVE combo, to a merge operation, so that the object (File) is just modified, or You could move the "contains" function outside of the moving function, so that it is not affected by the supposed Code Order Manipulation ( which actually works for me ).

Hope this helps someone.

这篇关于ArrayCollection(Doctrine)包含函数返回不正确的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆