在PHP中,我可以使用私有/受保護的$id
變量創建模型並且不設置setter。Doctrine如何設置私人ID
Doctrine ORM能夠在保存/加載對象時設置該屬性。
這是如何在內部工作的?我認爲這是通過序列化來處理的,但是我一直無法找到對此行爲負責的代碼。
在PHP中,我可以使用私有/受保護的$id
變量創建模型並且不設置setter。Doctrine如何設置私人ID
Doctrine ORM能夠在保存/加載對象時設置該屬性。
這是如何在內部工作的?我認爲這是通過序列化來處理的,但是我一直無法找到對此行爲負責的代碼。
第一次學說實例化一個實體(如User
),它這樣做:
$this->prototype = unserialize(sprintf('O:%d:"%s":0:{}', strlen($this->name), $this->name));
哪個不調用構造函數(反序列化避免了__construct
的調用創建該類型的對象,他們這樣做有意無意地讓他們不必擔心你的構造函數看起來像什麼或者做什麼)。
第一個對象初始化後,Doctrine使用clone
來創建相同對象類型的新實例。
$entity = clone $this->prototype;
從克隆的對象,它會:
$reflection = new \ReflectionObject($entity);
$property = $reflection->getProperty('idField');
$property->setAccessible(true);
$property->setValue($entity, 123);
實際的代碼做,這是比較複雜的,由於從複合主鍵主義的支持,但這樣應該可以指導你正確的方向。
Doctrine ORM使用reflection至assign identifiers。這在您的實體的class metadata中完成。
當ORM必須在內部實例化它們而不使用構造函數參數時,您的實體的非序列化is only used to create new instances(藍圖)。一旦藍圖可用,就會爲每個新請求的實例進行克隆。
在您的實體的官方網站explaining how Doctrine creates new instances上有一篇博文。