ホームページ > バックエンド開発 > PHPチュートリアル > ドクトリンエンティティで特性を使用します

ドクトリンエンティティで特性を使用します

Jennifer Aniston
リリース: 2025-02-19 09:20:11
オリジナル
581 人が閲覧しました

ドクトリンエンティティで特性を使用します

キーテイクアウト

    PHP 5.4.0以降利用可能な
  • 特性は、別のクラスに一連のメソッドを含めることでコードを再利用する方法を提供し、コードの繰り返しを削減します。それらは、symfony環境で教義ORMと組み合わせて使用​​できます。
  • 特性をインターフェイスと混同しないでください。インターフェイスはオブジェクトができることを示す契約ですが、特性はオブジェクトにそれを行う能力を与えます。
  • 特性は、データベースアーキテクチャの整理やコードの複製を回避するのに特に役立ちます。たとえば、「created_at」と「updated_at」フィールドの両方を必要とする記事とコメントのエンティティを作成する場合、これらの共通のプロパティを繰り返しを避けるために特性に含めることができます。
  • 特性は、より軽くて柔軟なコードを生成するための優れたツールですが、使いすぎてはいけません。ユニークなクラスの実装を構築する方が良い場合があります。アプリケーションを適切に設計するのに十分な時間をかけることが重要です。
  • PHP 5.4.0以来、PHPは「特性」と呼ばれるコードを再利用するためのかなりの方法をサポートしています。以前に公開されたSitePoint投稿で特性について詳しく読むことができます。
今日、私はそれらがSymfony環境でDoctrine ormでどのように使用できるかをお見せします。

特性の基本

ドクトリンエンティティで特性を使用します

ご覧のとおり、基本的な方法Sayhello()は、使用ステートメントを使用してAとBの両方のクラスによって実装される特性内で宣言されます。簡単ですよね?この例は本当に短いですが、特性を扱うための基本的な知識を提供するはずです。

特性に興味がある場合は、公式のドキュメントを読んで以前に公開されたSitePointの投稿をここ、ここで、概念を完全に把握することをお勧めします。

多くの人が特性とインターフェイスの違いを見ない傾向がないという事実について警告してください。ここに実用的な説明があります:

<span><span><?php
</span></span><span><span>trait ExampleTrait {
</span></span><span>    <span>public function sayHello() {
</span></span><span>        <span>echo "Hello";
</span></span><span>    <span>}
</span></span><span><span>}
</span></span><span>
</span><span><span>class A {
</span></span><span>    <span>use ExampleTrait;
</span></span><span><span>}
</span></span><span>
</span><span><span>class B {
</span></span><span>    <span>use ExampleTrait;
</span></span><span><span>}
</span></span><span>
</span><span><span>$one = new A();
</span></span><span><span>$one->sayHello();    /* return `Hello` */
</span></span><span>
</span><span><span>$two = new B();
</span></span><span><span>$two->sayHello();    /* return `Hello`, too */</span></span>
ログイン後にコピー
ログイン後にコピー

インターフェイスは「このオブジェクトはこのことを行うことができる」という契約ですが、特性はオブジェクトに物事を行う能力を与えています。

より詳細な説明については、以前の引用が由来するフィリップ・ブラウンによるこの洞察に満ちた投稿を見てください。
データベースアーキテクチャの整理に関しては、コードの複製に直面することは珍しくありません。例として、通常のブログアプリケーションを開発する必要があるとします。ある時点で、基本的な記事エンティティとおそらくコメントエンティティも作成する可能性があります。

両方のエンティティは、created_atおよびupdated_atフィールドを持っていることから利益を得るでしょう(したがって、これらの列で結果を並べ替えることができます)。しかし、特性を掘り下げる前に、それらなしでそれらのエンティティを教義で構築する方法を見てみましょう。

ステップ1:エンティティを作成

記事エンティティ

<span><span><?php
</span></span><span><span>trait ExampleTrait {
</span></span><span>    <span>public function sayHello() {
</span></span><span>        <span>echo "Hello";
</span></span><span>    <span>}
</span></span><span><span>}
</span></span><span>
</span><span><span>class A {
</span></span><span>    <span>use ExampleTrait;
</span></span><span><span>}
</span></span><span>
</span><span><span>class B {
</span></span><span>    <span>use ExampleTrait;
</span></span><span><span>}
</span></span><span>
</span><span><span>$one = new A();
</span></span><span><span>$one->sayHello();    /* return `Hello` */
</span></span><span>
</span><span><span>$two = new B();
</span></span><span><span>$two->sayHello();    /* return `Hello`, too */</span></span>
ログイン後にコピー
ログイン後にコピー

コメントエンティティ

<span><span><?php
</span></span><span><span>namespace Blog<span>\AppBundle\Entity</span>;
</span></span><span>
</span><span><span>use Doctrine<span>\ORM\Mapping</span> as ORM;
</span></span><span>
</span><span><span>/**
</span></span><span><span> * @ORM\Table(name="article")
</span></span><span><span> * @ORM\Entity(repositoryClass="Blog\AppBundle\Entity\ArticleRepository")
</span></span><span><span> */
</span></span><span><span>class Article
</span></span><span><span>{
</span></span><span>    <span>/**
</span></span><span><span>     * @ORM\Column(name="idArticle" type="integer")
</span></span><span><span>     * @ORM\Id()
</span></span><span><span>     * @ORM\GeneratedValue(strategy="AUTO")
</span></span><span><span>     */
</span></span><span>    <span>private $id;
</span></span><span>
</span><span>    <span>/* Other properties you need in your entity: $title, $content, $author...  */
</span></span><span>
</span><span>    <span>/** @ORM\Column(name="created_at" type="datetime") */
</span></span><span>    <span>private $createdAt;
</span></span><span>
</span><span>    <span>/** @ORM\Column(name="updated_at" type="datetime") */
</span></span><span>    <span>private $updatedAt;
</span></span><span>
</span><span>   <span>/* Getters & Setters */
</span></span><span><span>}</span></span>
ログイン後にコピー

同じプロパティ$ createdatと$ updatedatが両方のクラスに含まれています。これは乾燥にはほど遠いです。特性は、このコードをきれいにするのに役立つでしょうか?

ステップ2:特性を作成します

<span><span><?php
</span></span><span><span>namespace Blog<span>\AppBundle\Entity</span>;
</span></span><span>
</span><span><span>use Doctrine<span>\ORM\Mapping</span> as ORM;
</span></span><span>
</span><span><span>/**
</span></span><span><span> * @ORM\Table(name="comment")
</span></span><span><span> * @ORM\Entity(repositoryClass="Blog\AppBundle\Entity\CommentRepository")
</span></span><span><span> */
</span></span><span><span>class Comment
</span></span><span><span>{
</span></span><span>    <span>/**
</span></span><span><span>     * @ORM\Column(name="idComment" type="integer")
</span></span><span><span>     * @ORM\Id()
</span></span><span><span>     * @ORM\GeneratedValue(strategy="AUTO")
</span></span><span><span>     */
</span></span><span>    <span>private $id;
</span></span><span>
</span><span>    <span>/* Other properties you need in your entity */
</span></span><span>
</span><span>    <span>/** @ORM\Column(name="created_at" type="datetime") */
</span></span><span>    <span>private $createdAt;
</span></span><span>
</span><span>    <span>/** @ORM\Column(name="updated_at" type="datetime") */
</span></span><span>    <span>private $updatedAt;
</span></span><span>
</span><span>    <span>/* Getters & Setters */
</span></span><span><span>}</span></span>
ログイン後にコピー
ここに、最初の複製コードを移動したかなりの特性ファイルがあります。 $ createdatと$ updatedatの両方、および関連するすべてのメソッドの両方が、エンティティから分離されました。その結果、他の場所でそれらを使用する方がはるかに簡単になります。キーワードを使用した紹介セクションを覚えておいてください

ステップ3:エンティティをリファクタリングします

記事エンティティ

コメントエンティティ
<span><span><?php
</span></span><span><span>// src/Blog/AppBundle/Entity/Traits/TimestampableTrait.php
</span></span><span>
</span><span><span>namespace Blog<span>\AppBundle\Entity\Traits</span>;
</span></span><span>
</span><span><span>use Doctrine<span>\ORM\Mapping</span> as ORM;
</span></span><span>
</span><span><span>trait TimestampableTrait
</span></span><span><span>{
</span></span><span>    <span>/**
</span></span><span><span>     * <span>@var datetime $createdAt
</span></span></span><span><span>     *
</span></span><span><span>     * @ORM\Column(name="created_at", type="datetime")
</span></span><span><span>     */
</span></span><span>    <span>private $createdAt;
</span></span><span>
</span><span>    <span>/**
</span></span><span><span>     * <span>@var datetime $updatedAt
</span></span></span><span><span>     *
</span></span><span><span>     * @ORM\Column(name="updated_at", type="datetime")
</span></span><span><span>     */
</span></span><span>    <span>private $updatedAt;
</span></span><span>
</span><span>
</span><span>    <span>/**
</span></span><span><span>     * Get createdAt
</span></span><span><span>     *
</span></span><span><span>     * <span>@return datetime
</span></span></span><span><span>     */
</span></span><span>    <span>public function getCreatedAt()
</span></span><span>    <span>{
</span></span><span>        <span>return $this->createdAt;
</span></span><span>    <span>}
</span></span><span>
</span><span>    <span>/**
</span></span><span><span>     * Set createdAt
</span></span><span><span>     *
</span></span><span><span>     * <span>@param datetime $createdAt
</span></span></span><span><span>     */
</span></span><span>    <span>public function setCreatedAt($createdAt)
</span></span><span>    <span>{
</span></span><span>        <span>$this->createdAt = $createdAt;
</span></span><span>
</span><span>        <span>return $this;
</span></span><span>    <span>}
</span></span><span>
</span><span>    <span>/**
</span></span><span><span>     * Get updatedAt
</span></span><span><span>     *
</span></span><span><span>     * <span>@return datetime
</span></span></span><span><span>     */
</span></span><span>    <span>public function getUpdatedAt()
</span></span><span>    <span>{
</span></span><span>        <span>return $this->updatedAt;
</span></span><span>    <span>}
</span></span><span>
</span><span>    <span>/**
</span></span><span><span>     * Set updatedAt
</span></span><span><span>     *
</span></span><span><span>     * <span>@param datetime $updatedAt
</span></span></span><span><span>     */
</span></span><span>    <span>public function setUpdatedAt($updatedAt)
</span></span><span>    <span>{
</span></span><span>        <span>$this->updatedAt = $updatedAt;
</span></span><span>
</span><span>        <span>return $this;
</span></span><span>    <span>}
</span></span><span><span>}</span></span>
ログイン後にコピー

完了!コマンドラインで遊んでみましょう。まず、データベース内のエンティティを作成しましょう:
<span><span><?php
</span></span><span><span>// src/Blog/AppBundle/Entity/Article.php
</span></span><span>
</span><span><span>namespace Blog<span>\AppBundle\Entity</span>;
</span></span><span>
</span><span><span>use Doctrine<span>\ORM\Mapping</span> as ORM;
</span></span><span><span>use Blog<span>\AppBundle\Entity\Traits\TimestampableTrait</span>;
</span></span><span>
</span><span><span>class Article
</span></span><span><span>{
</span></span><span>    <span>use TimestampableTrait;
</span></span><span>
</span><span>    <span>/**
</span></span><span><span>     * @ORM\Column(name="idArticle" type="integer")
</span></span><span><span>     * @ORM\Id()
</span></span><span><span>     * @ORM\GeneratedValue(strategy="AUTO")
</span></span><span><span>     */
</span></span><span>    <span>private $id;
</span></span><span>
</span><span>    <span>/* Other properties you need in your entity */
</span></span><span>
</span><span>    <span>/* Getters & Setters */
</span></span><span><span>}</span></span>
ログイン後にコピー

このコマンドは、

を獲得します
<span><span><?php
</span></span><span><span>// src/Blog/AppBundle/Entity/Comment.php
</span></span><span>
</span><span><span>namespace Blog<span>\AppBundle\Entity</span>;
</span></span><span>
</span><span><span>use Doctrine<span>\ORM\Mapping</span> as ORM;
</span></span><span><span>use Blog<span>\AppBundle\Entity\Traits\TimestampableTrait</span>;
</span></span><span>
</span><span><span>/**
</span></span><span><span> * @ORM\Table(name="comment")
</span></span><span><span> * @ORM\Entity(repositoryClass="Blog\AppBundle\Entity\CommentRepository")
</span></span><span><span> */
</span></span><span><span>class Comment
</span></span><span><span>{
</span></span><span>    <span>use TimestampableTrait;
</span></span><span>
</span><span>    <span>/**
</span></span><span><span>     * @ORM\Column(name="idComment" type="integer")
</span></span><span><span>     * @ORM\Id()
</span></span><span><span>     * @ORM\GeneratedValue(strategy="AUTO")
</span></span><span><span>     */
</span></span><span>    <span>private $id;
</span></span><span>
</span><span>    <span>/* Other properties you need in your entity */
</span></span><span>
</span><span>    <span>/* Getters & Setters */
</span></span><span><span>}</span></span>
ログイン後にコピー

ここで、これらのクラスから新しいオブジェクトを作成したい場合、それらは両方とも利用可能な共通の方法を持っていることがわかります。

php app/console doctrine:schema:create
ログイン後にコピー
明らかに、データを保持する準備ができました。

さらに進む
`Article Entity`
	
	| idArticle | *All our other fields...* | created_at | updated_at |
	|-----------|---------------------------|------------|------------|
	
	`Comment Entity`
	
	| idComment | *All our other fields...* | created_at | updated_at |
	|-----------|---------------------------|------------|------------|
ログイン後にコピー

現在、Symfony Sphereでは、多くのバンドルと拡張機能がこの方法に固執する傾向があります。 KnplabsのDoctrinebehaviors Libraryは、エンティティとリポジトリの特性の優れたコレクションを提供します。同じ心の状態では、よく知られている教義Xtensionsバンドル、特にタイムスタンプ可能な動作の拡張に関するすべてを詳細に見ることをお勧めします。

最終的な考え

特性を吸収するのは難しくありません。それらは、より軽くてより柔軟なコードを作成するための優れた方法です。それらを悪用しないように注意してください。時には、ユニークなクラスの実装を構築することをお勧めします。アプリを適切に設計するために十分な時間をかけることがどれほど重要であるかを十分に強調することはできません。あなたが彼らがあなたを助けることができると思うなら、彼らに試してみてください。あなたのものを作成し、それらをテストし、あなたがそれらをどのように使用したかを教えてください!

教義の実体での特性の使用に関するよくある質問(FAQ)

教義のエンティティで特性を使用することの利点は何ですか?

教義のエンティティの特性は、複数の継承をサポートしていないPHPなどの言語でコードを再利用する方法を提供します。さまざまなクラスに挿入して追加の機能を提供できる再利用可能なコードスニペットを作成できます。これにより、複数のクラスでコードの複製を避けることができないため、よりクリーンで保守可能なコードにつながる可能性があります。特性は、使用されているクラスのメソッドをオーバーライドするためにも使用して、柔軟な方法で動作を変更するための強力なツールを提供することもできます。

教義の実体で特性を使用するにはどうすればよいですか?

教義のエンティティで特性を使用するには、まず特性を定義する必要があります。これは、特性キーワードを使用して行われ、その後、特性の名前と、特性が提供するメソッドとプロパティを含むコードブロックが行われます。特性が定義されたら、クラスの定義内に使用ステートメントを追加し、その後の特性の名前を追加することで、クラスで使用できます。これにより、クラスで利用可能な特性のすべての方法とプロパティが作成されます。

単一の教義エンティティで複数の特性を使用できますか?実在物。これは、クラス定義内に複数の使用ステートメントを追加することで行われ、それぞれが異なる特性の名前が続きます。すべての特性の方法と特性は、クラスで利用可能になります。さまざまな特性のメソッドまたはプロパティの間に命名の競合がある場合、代わりに、および演算子としてそれを解決できます。 、彼らはクラスではなく、コンストラクターの注入をサポートしていないためです。ただし、特性を使用するクラスにサービスを挿入できます。特性の方法は、クラスを介してこれらのサービスにアクセスできます。

特性は、教義の実体の方法を無効にすることができますか?クラスのメソッドと同じ名前で特性のメソッドを定義することによって行われます。メソッドがクラスのオブジェクトで呼び出されると、特性のバージョンがクラスのバージョンの代わりに使用されます。 、継承と組み合わせて特性を使用できます。クラスは親クラスから継承し、1つ以上の特性を使用できます。親クラスと特性の方法と特性はすべてクラスで利用可能になります。親クラスと特性のメソッドまたはプロパティの間に命名対立がある場合、特性のバージョンが使用されます。特性は、コードの再利用と柔軟性のための強力なツールを提供し、いくつかの制限と潜在的な欠点もあります。 1つの制限は、特性を単独でインスタンス化できないことです。クラス内でのみ使用できます。また、複数の特性が同じ名前のメソッドを定義する場合、手動で解決する必要がある競合を命名する可能性があります。特性の過剰使用は、理解して維持するのが難しいコードにつながる可能性があるため、賢明に使用する必要があります。

特性を使用する教義の実体をテストするにはどうすればよいですか?

特性を使用する教義のエンティティをテストすることは、通常の教義エンティティのテストに似ています。エンティティをインスタンス化するユニットテストを作成し、その方法を呼び出して、予想どおりに動作することを確認できます。特性が追加の方法を提供する場合、これらを同じ方法でテストできます。特性がエンティティ内のメソッドをオーバーライドする場合、メソッドの元のバージョン(特性を使用しないエンティティでテストすることで)とオーバーライドバージョン(特性を使用するエンティティでテストすることにより)の両方をテストする必要があります。 。

以上がドクトリンエンティティで特性を使用しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート