何が可能で、何が不可能で、計画されているのかを例を挙げて明確にしようと思います。
マニュアルからの引用は、基本的に、次のカスタム実装タイプを持つことができることを意味します。
use Doctrine\Common\Collections\Collection;
// MyCollection is the "implementation type"
class MyCollection implements Collection {
// ... interface implementation
// This is not on the Collection interface
public function myCustomMethod() { ... }
}
これで、次のように使用できます。
class MyEntity {
private $items;
public function __construct() {
$this->items = new MyCollection;
}
// ... accessors/mutators ...
}
$e = new MyEntity;
$e->getItems()->add(new Item);
$e->getItems()->add(new Item);
$e->getItems()->myCustomMethod(); // calling method on implementation type
// $em instanceof EntityManager
$em->persist($e);
// from now on $e->getItems() may only be used through the interface type
つまり、エンティティがNEW(MANAGED、DETACHED、またはREMOVEDではない)である限り、具体的な実装タイプのコレクションを自由に使用できます。NEWでない場合は、インターフェイスタイプのみにアクセスする必要があります(理想的には、タイプヒントにアクセスする必要があります)。つまり、実装タイプは実際には重要ではありません。永続的なMyEntityインスタンスがデータベースから取得されるとき、MyCollectionは使用されません(Doctrineは既存の/永続的なオブジェクトのみを再構成するため、コンストラクターはDoctrineによって呼び出されません。「新しい」オブジェクトを作成することはありません)。そして、そのようなエンティティは管理されているので、アクセスはとにかくインターフェースタイプを介して行われる必要があります。
今、計画されていることに。カスタムコレクションを作成するためのより美しい方法は、実装タイプとしてIMyCollectionやMyCollectionなどのカスタムインターフェイスタイプも使用することです。次に、Doctrine 2永続化サービスで完全に機能させるには、次のようなカスタムPersistentCollection実装(たとえば、MyPersistentCollection)を実装する必要があります。
class MyPersistentCollection implements IMyCollection {
// ...
}
次に、マッピングでDoctrineにそのコレクションにMyPersistentCollectionラッパーを使用するように指示します(PersistentCollectionはコレクション実装タイプをラップし、同じインターフェイスを実装するため、基になるコレクション実装に委任する前/後にすべての永続化作業を実行できますタイプ)。
したがって、カスタムコレクションの実装は次の3つの部分で構成されます。
- インターフェイスタイプ
- 実装タイプ(インターフェースタイプを実装)
- 永続ラッパータイプ(インターフェイスタイプを実装)
これにより、Doctrine 2 ORMで機能しないように見えるカスタムコレクションを作成できるだけでなく、特定のアプリケーションのニーズに合わせて特定のコレクションの遅延読み込み/初期化動作を最適化するなど、カスタムの永続ラッパータイプのみを作成することもできます。
これを行うことはまだ可能ではありませんが、可能になります。これは、Doctrine 2が提供する透過的な永続化スキームに完璧に統合された、完全にカスタムのコレクションを作成して使用するための、本当にエレガントで完全に機能する唯一の方法です。