Symfony 2およびDoctrine 2

Symfony 2の研究を続け、これは最もよくある質問の1つであるため、Doctrine 2とともにフレームワークの使用について説明することにしました。 そして、Doctrine 2も1.xブランチと比較して大きな変更を受けていることは注目に値します。 Doctrineプロジェクト自体は非常に大きいので、その説明はおそらく小さいながらも興味深い本になります。 したがって、Symfony 2でDoctrine 2を使用する例を非常に簡単に説明します。これにより、このバンドルの実行方法を理解でき、非常に小さくシンプルなアプリケーションの例を使用してこれを実行できます。



Doctrine 2について



始めに、Doctrine 2についての簡単な紹介を行います。プロジェクトは現在3つのパッケージに分割されています。



共通 -他のパッケージで使用される共通コンポーネントが含まれています。

DBAL-データベースアクセス抽象化レイヤー。

ORM-オブジェクトリレーショナルマッピングツール



Doctrine 2には、以前の* Tableおよび* Recordクラスになじみのあるものはありません。 また、モデルクラスがレコードクラスを継承する必要がなくなり、テーブルクラスがDoctrineパッケージからテーブルクラスを継承することも意味します。 代わりに、2つの新しい概念、EntityとEntityManagerが導入されています。 エンティティは、大まかに言って、モデルのオブジェクトであり、EntityManagerは、エンティティオブジェクトをそれぞれ管理できるクラスです。 おもしろいことは、「Entity」は任意のPHPクラスであり、Doctrineパッケージからクラスを継承しないことです。



Doctrine 1では、モデルはYamlファイルで記述されていましたが、現在はYaml、XML、またはDocblockアノテーションを使用できます。 おそらく、PHPDocumentorでメソッドを記述するために、だれでも何らかの形でDocblockアノテーションを使用する必要がありました。 そのため、永続オブジェクトのメタデータを記述することもできます。

例:

Copy Source | Copy HTML <?php /** <br/> * @Entity <br/> * @Table(name="my_model") <br/> */ class MyModel { /** <br/> * @Id @Column(name="id", type="integer") <br/> * @GeneratedValue(strategy="AUTO") <br/> */ private $id ; /** <br/> * @Column(name="title", type="string", length=255) <br/> */ private $title ; }



  1. Copy Source | Copy HTML <?php /** <br/> * @Entity <br/> * @Table(name="my_model") <br/> */ class MyModel { /** <br/> * @Id @Column(name="id", type="integer") <br/> * @GeneratedValue(strategy="AUTO") <br/> */ private $id ; /** <br/> * @Column(name="title", type="string", length=255) <br/> */ private $title ; }



  2. Copy Source | Copy HTML <?php /** <br/> * @Entity <br/> * @Table(name="my_model") <br/> */ class MyModel { /** <br/> * @Id @Column(name="id", type="integer") <br/> * @GeneratedValue(strategy="AUTO") <br/> */ private $id ; /** <br/> * @Column(name="title", type="string", length=255) <br/> */ private $title ; }



  3. Copy Source | Copy HTML <?php /** <br/> * @Entity <br/> * @Table(name="my_model") <br/> */ class MyModel { /** <br/> * @Id @Column(name="id", type="integer") <br/> * @GeneratedValue(strategy="AUTO") <br/> */ private $id ; /** <br/> * @Column(name="title", type="string", length=255) <br/> */ private $title ; }



  4. Copy Source | Copy HTML <?php /** <br/> * @Entity <br/> * @Table(name="my_model") <br/> */ class MyModel { /** <br/> * @Id @Column(name="id", type="integer") <br/> * @GeneratedValue(strategy="AUTO") <br/> */ private $id ; /** <br/> * @Column(name="title", type="string", length=255) <br/> */ private $title ; }



  5. Copy Source | Copy HTML <?php /** <br/> * @Entity <br/> * @Table(name="my_model") <br/> */ class MyModel { /** <br/> * @Id @Column(name="id", type="integer") <br/> * @GeneratedValue(strategy="AUTO") <br/> */ private $id ; /** <br/> * @Column(name="title", type="string", length=255) <br/> */ private $title ; }



  6. Copy Source | Copy HTML <?php /** <br/> * @Entity <br/> * @Table(name="my_model") <br/> */ class MyModel { /** <br/> * @Id @Column(name="id", type="integer") <br/> * @GeneratedValue(strategy="AUTO") <br/> */ private $id ; /** <br/> * @Column(name="title", type="string", length=255) <br/> */ private $title ; }



  7. Copy Source | Copy HTML <?php /** <br/> * @Entity <br/> * @Table(name="my_model") <br/> */ class MyModel { /** <br/> * @Id @Column(name="id", type="integer") <br/> * @GeneratedValue(strategy="AUTO") <br/> */ private $id ; /** <br/> * @Column(name="title", type="string", length=255) <br/> */ private $title ; }



  8. Copy Source | Copy HTML <?php /** <br/> * @Entity <br/> * @Table(name="my_model") <br/> */ class MyModel { /** <br/> * @Id @Column(name="id", type="integer") <br/> * @GeneratedValue(strategy="AUTO") <br/> */ private $id ; /** <br/> * @Column(name="title", type="string", length=255) <br/> */ private $title ; }



  9. Copy Source | Copy HTML <?php /** <br/> * @Entity <br/> * @Table(name="my_model") <br/> */ class MyModel { /** <br/> * @Id @Column(name="id", type="integer") <br/> * @GeneratedValue(strategy="AUTO") <br/> */ private $id ; /** <br/> * @Column(name="title", type="string", length=255) <br/> */ private $title ; }







そしてもちろん、あなたはDoctrineのウェブサイトでこれらすべてについてもっと読むことができます



離陸



非常に小さくて非常にシンプルなアプリケーションの例として、Doctrine 2の使用を検討することにしました。 これはReadlaterサービスになり、リンクを保存して後で読むまで延期することができます。 つまり、すべての機能が3つの単純なアクションに削減されます。



しかし、私はすぐに小さな問題に遭遇しました-Doctrine 2とSymfony 2の両方が現在活発に開発されており、安定性の問題はありません。 さらに、すべてが非常に頻繁に変化し、今日動作するものは明日は離陸しないかもしれません。 多くの場合、これらはコードを別のディレクトリに移動するなど、さまざまな小さなものです。 したがって、このアプリケーションでは、使用するライブラリのバージョンを凍結することにしました。 このために、私は取りました:



これらすべてをまとめて、2010年4月18日にすべてのバージョンを元の形式に固定し、アプリケーションと一緒にgithubで共有しました。 あなたが興味を持っているのであれば、それのために行きます。



飛んだ



したがって、最初は構造について簡単に説明します。 この種類のディレクトリについて:



構成から始めましょう。 readlater / config / config.ymlに以下を追加します:

Copy Source | Copy HTML



  1. カーネル。 構成 :〜
  2. ウェブ ウェブ :〜
  3. ウェブ テンプレート化 :〜
  4. 教義。 dbal
  5. default_connectionデフォルト
  6. 接続
  7. デフォルト
  8. ドライバー :PDOMySql
  9. dbname :sfbox2
  10. ユーザー :ルート
  11. パスワード123
  12. ホスト :localhost
  13. event_manager_class :Doctrine \ Common \ EventManager
  14. configuration_class :Doctrine \ DBAL \設定
  15. 教義。 orm
  16. default_entity_managerデフォルト
  17. cache_driver :配列
  18. entity_managers
  19. デフォルト
  20. 接続デフォルト


doctrine.dbalデータベースへの接続と、Doctrine \ ORMパッケージdoctrine.ormの設定について説明しました

ここではアプリケーションコアの作成については説明しません。symfony-sandboxで行われるものと実質的に変わらないからです。

したがって、 src / Applicationに配置したReadlaterBundleに進み ます 。 バンドルの構造は次のとおりです。



エンティティディレクトリでは、これ以上必要ないため、単一のLinkクラスを作成します。 Doctrine 2はデフォルトでバンドルエンティティディレクトリにエンティティを作成することを提案します。つまり、各バンドルは独自のモデルクラスのセットを持つことができます。 設定として、DoctrineにEntities以外のディレクトリでクラスを検索するように依頼できますが、私はこれを行いません。

Linkクラスのコードは次のとおりです。

Copy Source | Copy HTML



  1. <?php
  2. 名前空間 Application \ ReadlaterBundle \ Entities;
  3. Doctrine \ ORM \ EntityRepositoryを使用します。
  4. / ** <br/> * @Entity <br/> * @Table(name = "readlater_link") <br/> * /
  5. クラスリンク
  6. {
  7. / ** <br/> * @Id @Column(name = "id"、type = "integer") <br/> * @GeneratedValue(strategy = "AUTO") <br/> * /
  8. プライベート $ id ;
  9. / ** <br/> * @Column(name = "url"、type = "string"、length = 255) <br/> * /
  10. プライベート $ url ;
  11. / ** <br/> * @Column(name = "created_at"、type = "datetime") <br/> * /
  12. private $ createdAt ;
  13. / ** <br/> *コンストラクター <br/> * /
  14. パブリック関数 __construct()
  15. {
  16. $ this-> createdAt = new \ DateTime ();
  17. }
  18. / ** <br/> *文字列 <br/>へ* /
  19. パブリック関数 __toString()
  20. {
  21. return $ this-> getUrl();
  22. }
  23. }


クラスで3つのフィールドを定義しました。



また、すでに明確な2つのメソッドも追加しました。 例からわかるように、Docblockを使用してモデルを説明しました。

いくつかのコマンドを実行しました:



readlater/console doctrine:database:create

readlater/console doctrine:generate:entities

readlater/console doctrine:schema:create







最初のチームはデータベースを作成し、2番目はクラスのメソッドを生成して作業を行い、3番目はデータベースにテーブルを作成します。

次のようになります。







Linkクラスを調べると、少し変更されていることがわかりますが、次のようになります。

Copy Source | Copy HTML



  1. <?php
  2. 名前空間 Application \ ReadlaterBundle \ Entities;
  3. Doctrine \ ORM \ EntityRepositoryを使用します。
  4. / ** <br/> * @Entity <br/> * @Table(name = "readlater_link") <br/> * /
  5. クラスリンク
  6. {
  7. / ** <br/> * @Id @Column(name = "id"、type = "integer") <br/> * @GeneratedValue(strategy = "AUTO") <br/> * /
  8. プライベート $ id ;
  9. / ** <br/> * @Column(name = "url"、type = "string"、length = 255) <br/> * /
  10. プライベート $ url ;
  11. / ** <br/> * @Column(name = "created_at"、type = "datetime") <br/> * /
  12. private $ createdAt ;
  13. / ** <br/> *コンストラクター <br/> * /
  14. パブリック関数 __construct()
  15. {
  16. $ this-> createdAt = new \ DateTime ();
  17. }
  18. / ** <br/> *文字列 <br/>へ* /
  19. パブリック関数 __toString()
  20. {
  21. return $ this-> getUrl();
  22. }
  23. / ** <br/> * Get id <br/> * <br/> * @return integer $ id <br/> * /
  24. パブリック関数 getId()
  25. {
  26. $ this-> id;
  27. }
  28. / ** <br/> * URLを設定 <br/> * <br/> * @param string $ url <br/> * /
  29. パブリック関数 setUrl( $ url
  30. {
  31. $ this-> url = $ url ;
  32. }
  33. / ** <br/> * URLを取得 <br/> * <br/> * @return string $ url <br/> * /
  34. パブリック関数 getUrl()
  35. {
  36. return $ this-> url;
  37. }
  38. / ** <br/> *セットCreateAt <br/> * <br/> * @param datetime $ createdAt <br/> * /
  39. パブリック関数 setCreatedAt( $ createdAt
  40. {
  41. $ this-> createdAt = $ createdAt ;
  42. }
  43. / ** <br/> * Get CreateAt <br/> * <br/> * @return datetime $ createdAt <br/> * /
  44. パブリック関数 getCreatedAt()
  45. {
  46. return $ this-> createdAt;
  47. }
  48. }


クラスプロパティにアクセスするためのメソッドを導入しました。



ルーティングルールをrouting.ymlに追加します

Copy Source | Copy HTML



  1. link_list
  2. パターン :/
  3. デフォルト{ _bundle :ReadlaterBundle、 _controller :Readlater、 _action :index }
  4. add_link
  5. パターン :/追加
  6. デフォルト{ _bundle :ReadlaterBundle、 _controller :Readlater、 _action :add }
  7. read_link
  8. パターン :/読み取り/:id
  9. デフォルト{ _bundle :ReadlaterBundle、 _controller :Readlater、 _action :read }


コードから、すべてが明確であると思います。リスト、追加、削除の3つのルールがあります。



最後に、Doctrineを実行しているオブジェクトを操作する方法を確認できるコントローラーです。 コード全体をすぐに引用します。

Copy Source | Copy HTML



  1. <?php
  2. 名前空間 Application \ ReadlaterBundle \ Controller;
  3. Symfony \ Framework \ WebBundle \ Controllerを使用し、
  4. アプリケーション\ ReadlaterBundle \エンティティ\リンク、
  5. Doctrine \ ORM \ QueryBuilder;
  6. ReadlaterController クラス Controllerを拡張します
  7. {
  8. パブリック関数 indexAction()
  9. {
  10. $ em = $ this-> container-> getDoctrine_ORM_EntityManagerService();
  11. $ links = $ em-> getRepository( 'Application \\ ReadlaterBundle \ Entities \ Link' )-> findAll();
  12. return $ this- > render( 'ReadlaterBundle:Readlater:index'array'links' => $ links ));
  13. }
  14. パブリック関数 addAction()
  15. {
  16. $ request = $ this-> getRequest();
  17. $ url = $ request-> request-> get( 'link' );
  18. $ link = new Link();
  19. $ link-> setUrl( $ url );
  20. $ em = $ this-> container-> getDoctrine_ORM_EntityManagerService();
  21. $ em- > persist( $ link );
  22. $ em- > flush();
  23. return $ this- > redirect( $ this- > generateUrl( 'link_list' ));
  24. }
  25. パブリック関数 readAction( $ id
  26. {
  27. $ em = $ this-> container-> getDoctrine_ORM_EntityManagerService();
  28. $ link = $ em- > find( 'Application \\ ReadlaterBundle \\ Entities \\ Link'$ id );
  29. $ em- > remove( $ link );
  30. $ em- > flush();
  31. return $ this- > redirect( $ this- > generateUrl( 'link_list' ));
  32. }
  33. }


コードに関するいくつかの言葉。

$em = $this->container->getDoctrine_ORM_EntityManagerService();



したがって、DIコンテナを使用して、 EntityManagerにアクセスします

$em->getRepository()



-これは特定のタイプのオブジェクト、つまり何らかのアナログのオブジェクトのストレージを取得する方法です* Doctrine 1.xのテーブル。

$em->persist($link);



-オブジェクトを保存します

$em->flush()



トランザクションを完了します。つまり、実際にデータベースにデータを送信します。

$em->remove($link)



- $em->remove($link)



、オブジェクトを削除してください。

ところで、 Symfony \ Framework \ DoctrineBundle \ Controller \ DoctrineControllerからコントローラーを継承した場合、メソッドは利用可能になります:



これがコードのすべてです。残りは明らかだと思います。



しかし、おそらくテーブルクラスがない場合、モデルオブジェクトを抽出するためのメソッドをどこで作成するかという疑問が生じました。 たとえば、この場合、 findAllメソッドが、降順で追加された日付でソートされたオブジェクトのリストを取得すると便利です。 これを行うには、特定のタイプのオブジェクト用に独自のストレージリポジトリクラスを作成します。

これを行うには、 Linkクラスを開き、ファイルの最後に追加します。

Copy Source | Copy HTML



  1. / ** <br/> * LinkRepository <br/> * /
  2. クラス LinkRepository EntityRepositoryを拡張します
  3. {
  4. パブリック関数 findAll()
  5. {
  6. return $ this- > _ em-> createQuery( 'SELECT l FROM Application \\ ReadlaterBundle \\ Entities \\ Link l ORDER BY l.createdAt DESC' )-> getResult();
  7. }
  8. }


これがリポジトリになります。

ここで、 Linkクラスに使用するリポジトリを考えてみましょう。このため、 LinkクラスのDocblockをわずかに変更します

Copy Source | Copy HTML



  1. / ** <br/> * @Entity(repositoryClass = "Application \ ReadlaterBundle \ Entities \ LinkRepository") <br/> * @Table(name = "readlater_link") <br/> * /
  2. クラスリンク
  3. {
  4. // ...
  5. }


それは基本的にそれです。 これで、リンクのリストは正しい順序でソートされ、次のようになります。





テンプレートコードは引用しませんでしたが、これらはすべてgithubのソースコードで確認できます

関連リンクも:




All Articles