Doctrine ORMの動作、または特性を効果的に使用する方法

php 5.4がリリースされてからしばらく経ちましたが、私たちは特性を実験し、その実用的なアプリケーションを評価することにしました。 Doctrine2オブジェクトでどのように使用できますか?



特性



PHPの特性は、クラスに追加できるプロパティとメソッドのセットです。

これらはインタープリターレベルで実装され、Doctrineに対して完全に透過的です。



特性は水平方向に再利用できるように設計されており、複数のオブジェクトに共通の動作を追加するのに最適です。



一般的な動作



多くの場合、 created_atおよびupdated_at属性を使用してオブジェクトを作成および更新する時間を節約する必要があります。 この動作は、あらゆるタイプのオブジェクトに適用できます。 そのような状況では、「毎回コードを繰り返すのを避けるにはどうすればよいですか?」



タイムスタンプ可能な動作



Timestampableは、Doctrineオブジェクトに適用できる単純な特性です:



<?php use Doctrine\ORM\Mapping as ORM; use Knp\DoctrineBehaviors\ORM as ORMBehaviors; /** * @ORM\Entity */ class Category { use ORMBehaviors\Timestampable\Timestampable; /** * @ORM\Id * @ORM\Column(type="integer") * @ORM\GeneratedValue(strategy="NONE") */ protected $id; }
      
      





クラス内のuseステートメントに注意してください。



このコードは、 DateTime型のDoctrineの2つのプロパティと、 createdAt値updatedAt値を取得する2つのパブリックメソッドを追加します



 <?php $category = new Category; $entityManager->persist($category); $category->getCreatedAt(); $category->getUpdatedAt();
      
      





オブジェクトを変更した後、 getUpdatedAtは最後の更新の日付を返します。



設置



タイムスタンプ可能およびその他の特性は、KnpLabs / DoctrineBehavioursのgithubリポジトリにまとめられます



composerを使用して簡単にインストールできます。 これらの行をプロジェクトのルートフォルダーのcomposer.jsonファイルに追加します。



 { "require": { "knplabs/doctrine-behaviors": "dev-master", } }
      
      





次に、composerを実行します。



 curl -s http://getcomposer.org/installer | php php composer.phar install
      
      





リスナー



Timestampableを使用するすべてのオブジェクトのイベントを持続または更新することを期待しているDoctrineリスナーのおかげで、これはすべて可能です。



しかし、すべてが機能するためには、それらを登録する必要があります。 Symfony2を使用すれば簡単です! サービス定義ファイルをインポートします。



 # app/config/config.yml imports: - { resource: ../../vendor/knplabs/doctrine-behaviors/config/orm-services.yml }
      
      





翻訳可能な動作



多くの場合、アプリケーションはプロパティが複数の言語で利用可能でなければならないオブジェクトを使用します。 このような場合の特性を可能な限り単純化しようとしました。



プロパティを変換できるオブジェクトを取得するには、2つの手順を実行する必要があります。



1. 翻訳可能な特性を使用する



 <?php use Doctrine\ORM\Mapping as ORM; use Knp\DoctrineBehaviors\ORM as ORMBehaviors; /** * @ORM\Entity */ class Category { use ORMBehaviors\Translatable\Translatable; /** * @ORM\Id * @ORM\Column(type="integer") * @ORM\GeneratedValue(strategy="NONE") */ protected $id; }
      
      





2. 翻訳特性を使用するカテゴリ翻訳オブジェクトを作成します。



 <?php use Doctrine\ORM\Mapping as ORM; use Knp\DoctrineBehaviors\ORM as ORMBehaviors; /** * @ORM\Entity */ class CategoryTranslation { use ORMBehaviors\Translatable\Translation; /** * @ORM\Column(type="string") */ protected $name; }
      
      





以上です! TranslatableListenerは、2つのオブジェクト間の関係を自動的に検出します。 通常のOneToMany接続と同じ方法でそれらを使用できます(たとえば、左結合を使用して翻訳を受信できます)。



 <?php $category = new Category; $category->translate('ru')->setName(''); $category->translate('en')->setName('Shoes'); $em->persist($category); $category->translate('en')->getName();
      
      





樹木



ツリーは、 マテリアライズドパスの実装を使用してツリーを操作します。 すべてのノードには、ルートからのフルパスが含まれています。



  | id | name | path | +-----+------------+------------+ | 1 | fr | /1 | | 2 | villes | /1/2 | | 4 | subNantes | /1/2/3/4 | | 7 | en | /7 | | 8 | villes | /7/8 | | 9 | Nantes | /7/8/9 | | 10 | subNantes | /7/8/9/10 | | 11 | Lorient | /7/8/11 | | 12 | Rouen | /7/8/12 | | 6 | Rouen | /1/2/6 | | 3 | Nantes | /1/2/3 | | 5 | Lorient | /1/2/5 |
      
      





オブジェクトをツリーとして表すには、 Tree \ Node traitを使用します



 <?php use Doctrine\ORM\Mapping as ORM; use Knp\DoctrineBehaviors\ORM as ORMBehaviors; /** * @ORM\Entity(repositoryClass="CategoryRepository") */ class Category { use ORMBehaviors\Tree\Node; /** * @ORM\Id * @ORM\Column(type="integer") * @ORM\GeneratedValue(strategy="NONE") */ protected $id; }
      
      





また、対応するEntityRepositoryTree \ Tree トレイトを使用する必要があります。



 <?php use Doctrine\ORM\EntityRepository; use Knp\DoctrineBehaviors\ORM as ORMBehaviors; class CategoryRepository extends EntityRepository { use ORMBehaviors\Tree\Tree; }
      
      





オブジェクトは、子オブジェクト、親などを操作するための一連のメソッドを提供します。



 $root = $em->getRepository('Category')->getTree(); $root->getParentNode(); $root->getChildren(); $root[0][1]; // array access of children $root->isLeafNode(); $root->isRootNode();
      
      







おわりに



この記事では、特性の実際的な適用のいくつかの例を検討しました。 説明されている特性に加えて、githubのREADMEファイルで完全なリストを確認できます。



ご注意 この記事は、私たちのブログで公開されている記事のロシア語版です: Doctrine ORMの振る舞い、または特性を効率的に使用する方法 英語版の作者:コンスタンチン・クドリャショフ(@everzet)、フロリアン・クライン、レシェク・プラバキ。 翻訳:アレクサンダー・トルチェンコ(@torchello)。



All Articles