PHP では、private/protected$id
変数を使用し、setter を使用しないモデルを作成できます。
Doctrine ORM は、オブジェクトが保存/ロードされるときにそのプロパティを設定できます。
これは内部でどのように機能しますか? これはシリアル化によって処理されると思いますが、この動作の原因となるコードを見つけることができませんでした。
PHP では、private/protected$id
変数を使用し、setter を使用しないモデルを作成できます。
Doctrine ORM は、オブジェクトが保存/ロードされるときにそのプロパティを設定できます。
これは内部でどのように機能しますか? これはシリアル化によって処理されると思いますが、この動作の原因となるコードを見つけることができませんでした。
初めて doctrine がエンティティ ( a など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 が複合主キーをサポートしているため、より複雑になりますが、うまくいけば正しい方向に導かれるはずです。
Doctrine ORM はリフレクションを使用して識別子を割り当てます。これは、エンティティのクラス メタデータで行われます。
非シリアル化は、ORM がコンストラクター パラメーターを使用せずに内部でインスタンス化する必要がある場合に、エンティティーの新しいインスタンス (ブループリント) を作成するためにのみ使用されます。ブループリントが利用可能になると、新しくリクエストされたインスタンスごとに複製されます。
公式 Web サイトには、 Doctrine がエンティティの新しいインスタンスを作成する方法を説明するブログ投稿があります。