Reputation: 8111
Using ORM
$timer = new Timer(); //an object marked as a Doctrine Entity
$this->em->persist($timer);
print $timer->getId(); //blank - not yet set
$this->em->flush($timer);
print $timer->getId(); //prints ID of newly inserted record
Actual ORM Code (Doctrine)
public function persist($entity)
{
if ( ! is_object($entity)) {
throw ORMInvalidArgumentException::invalidObject('EntityManager#persist()' , $entity);
}
$this->errorIfClosed();
$this->unitOfWork->persist($entity);
}
Question
How does Doctrine insert insert_id
into the Entity
, when the ORM's code above has no "pass by reference" directive?
I.e. normally I'd expect something like this:
public function persist(&$entity)
{
...
}
to indicate that the entity will be modified (with insert_id
) during the persist
process. But there is nothing of the sort. Nevertheless, Entity
is populated with insert_id
magically.
How does that happen exactly?
Upvotes: 2
Views: 915
Reputation: 813
Objects are passed (and assigned) by reference. No need to use address of operator.
One of the key-points of PHP 5 OOP that is often mentioned is that "objects are passed by references by default". This is not completely true. This section rectifies that general thought using some examples.
A PHP reference is an alias, which allows two different variables to write to the same value. As of PHP 5, an object variable doesn't contain the object itself as value anymore. It only contains an object identifier which allows object accessors to find the actual object. When an object is sent by argument, returned or assigned to another variable, the different variables are not aliases: they hold a copy of the identifier, which points to the same object.
Id set in UnitOfWork::executeInserts.
$postInsertIds = $persister->executeInserts();
if ($postInsertIds) {
// Persister returned post-insert IDs
foreach ($postInsertIds as $postInsertId) {
$id = $postInsertId['generatedId'];
$entity = $postInsertId['entity'];
$oid = spl_object_hash($entity);
$idField = $class->identifier[0];
$class->reflFields[$idField]->setValue($entity, $id);
Upvotes: 1