

Doctrine may modify other documents
At work, I am currently using MongoDB with Doctrine ODM.
The Problem
I have a document that are indirectly related to each other.
Let’s say I have a document called Posts
and the Posts
document has a function called getComments
that returns a CommentCollection
.
We also have a document called BackupComments
. The BackupComments
document is just a place to store a modified version of the comments.
Let’s say we want to modify the format of the date from comments and store it in the BackupComments
document.
$posts = $this->dm->getRepository(Posts::class)->findOne(); $comments = $posts->getComments();
// This will be where your problem is. We want to do it in an easy way foreach ($comments as $comment) { $backupComment = new BackupComments();
$modifiedComment = $comment->getComment(); $date = $comment->getDate(); $modifiedComment = $date->format('Y-m-d H:i:s') . ': ' . $modifiedComment;
$comment->setComment($modifiedComment);
$backupComment->setComment($modifiedComment); $this->dm->persist($backupComment); }
$this->dm->flush();
The problem with this code is that the Comment
document is being modified. This is because of how PHP references objects.
When you modify the $comment
object, you are also modifying the Comment
document indirectly.
Solution
Thankfully, this is very easy to fix. You can use the clone
keyword to create a new instance of the object or just modify the raw data.
We will use the latter method in this example.
$posts = $this->dm->getRepository(Posts::class)->findOne(); $comments = $posts->getComments();
foreach ($comments as $comment) { $backupComment = new BackupComments();
$modifiedComment = $comment->getComment(); $date = $comment->getDate(); $modifiedComment = $date->format('Y-m-d H:i:s') . ': ' . $modifiedComment;
$comment->setComment($modifiedComment);
// Just create a new instance of the Comment object $newComment = new Comment(); $newComment->setComment($modifiedComment);
// This will not modify the original Comment object $backupComment->setComment($modifiedComment); $this->dm->persist($backupComment); }
$this->dm->flush();
Now, the Comment
document will not be modified. The BackupComments
document will have the modified comments.
← Back to blog