Использование 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
Актуальный Кодекс ORM (Доктрина)
public function persist($entity)
{
if ( ! is_object($entity)) {
throw ORMInvalidArgumentException::invalidObject('EntityManager#persist()' , $entity);
}
$this->errorIfClosed();
$this->unitOfWork->persist($entity);
}
Вопрос
Как Доктрина вставить insert_id
в Entity
, когда в приведенном выше коде ORM нет директивы «передать по ссылке»?
То есть обычно я ожидаю что-то вроде этого:
public function persist(&$entity)
{
...
}
чтобы указать, что объект будет изменен (с insert_id
) в течение persist
процесс. Но нет ничего подобного. тем не менее, Entity
населён insert_id
волшебно.
Как это происходит в точности?
Объекты передаются (и присваиваются) по ссылке. Нет необходимости использовать адрес оператора.
Одним из ключевых моментов ООП PHP 5, который часто упоминается, является то, что «объекты передаются по ссылкам по умолчанию». Это не совсем верно. Этот раздел исправляет эту общую мысль, используя некоторые примеры.
Ссылка PHP — это псевдоним, который позволяет двум разным переменным записывать одно и то же значение. Начиная с PHP 5, переменная объекта больше не содержит сам объект в качестве значения. Он содержит только идентификатор объекта, который позволяет методам доступа к объекту найти фактический объект. Когда объект отправляется с помощью аргумента, возвращается или присваивается другой переменной, различные переменные не являются псевдонимами: они содержат копию идентификатора, который указывает на тот же объект.
Идентификатор установлен в 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);
Других решений пока нет …