首頁 > 後端開發 > php教程 > 在學說實體中使用特徵

在學說實體中使用特徵

Jennifer Aniston
發布: 2025-02-19 09:20:11
原創
583 人瀏覽過

在學說實體中使用特徵

鑰匙要點

    自PHP 5.4.0以來可用的特徵,提供了一種通過在另一類中包含一組方法,從而減少代碼重複來提供重複使用代碼的方法。它們可以與Symfony環境中的學說ORM結合使用。
  • >
  • 特徵不應與接口相混淆。界面是說明對象可以做什麼的合同,但特徵使對象具有執行功能。
  • >
  • 特徵在組織數據庫體系結構和避免代碼重複方面特別有用。例如,當創建需要“ create_at”和“ updated_at”字段的文章和評論實體時,這些常見屬性可以包含在特徵中以避免重複。
  • >
  • >特徵是生產更輕,更靈活的代碼的絕佳工具,但不應過度使用它們。有時,構建獨特的類實現可能會更好。花費足夠的時間正確設計您的應用程序至關重要。
  • 自PHP 5.4.0以來,PHP支持一種精美的方法來重用稱為“特徵”的代碼 - 您可以在另一類中包含的一組方法,以免重複自己。您可以在先前發布的SitePoint帖子中閱讀有關特徵的更多信息:此處,此處和此處。

今天,我將向您展示如何在符號環境中與學說ORM一起使用。

在學說實體中使用特徵特徵基礎

>正如我們所看到的,基本方法sayhello()在通過使用語句的A和B類實現的性狀中聲明。容易,對吧?這個示例確實很短,但是它應該為您提供基本知識來使用特質。

>
<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>
登入後複製
登入後複製
如果您對特徵感興趣,我建議您在此處和此處閱讀官方文檔和先前發布的SitePoint帖子,以充分掌握該概念。

請允許我警告您這樣一個事實,即許多人傾向於看不到特質和界面之間的區別。這是一個務實的解釋:


>接口是一份合同,上面寫著“此對象能夠做這件事”,而特徵使對象具有做事的能力。 >

要進行更深入的解釋,請隨時查看菲利普·布朗(Philip Brown)的這一有見地的帖子,以前的報價來自。

在組織數據庫體系結構方面,面對代碼重複並不少見。例如,假設我們必須開發通常的博客應用程序。在某個時候,我們可能會創建一個基本文章實體,也可能是一個評論實體。
>兩個實體將受益於創建的_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>
登入後複製

>在兩個類中都包含相同的屬性$創建和$ UPDATAT。這遠非干燥。特徵可以幫助我們清理此代碼嗎?

步驟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>
登入後複製

這是一個漂亮的特徵文件,我們已經移動了初始重複的代碼。 $ CREATTAT和$ UPDATAT以及所有相關方法現在都與實體分開。結果,在其他地方使用它們會更容易。請記住帶有關鍵字使用的介紹部分。

>步驟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的教義Behaviors庫為實體和存儲庫提供了很多特徵。在同一心態下,我建議您深入了解眾所周知的教義延期捆綁包,尤其是有關時間通知行為擴展的所有內容。

>

最終想法

特徵並不難吸收。它們是生產更輕,更靈活的代碼的絕佳方法。注意不要濫用它們:有時候,最好構建獨特的班級實現。我不能足夠強調花費足夠的時間才能正確設計您的應用是多麼重要。如果您認為他們可以幫助您,請試一試。創建您的,測試它們,並告訴我們您如何使用它們!

>關於在學說實體中使用特徵的常見問題(常見問題解答)

>在學說實體中使用特質的好處是什麼? >

>我如何在學說實體中使用特徵?

在學說實體中使用特質,您首先需要定義特徵。這是使用特徵關鍵字完成的,其次是特徵的名稱和一個包含特徵提供的方法和屬性的代碼塊。定義性狀後,您可以在類中添加使用語句,然後在特徵的名稱中添加使用語句來使用它。這將使課程中可用的特徵的所有方法和屬性。

我可以在單個學說實體中使用多個特徵嗎?實體。這是通過在類定義中添加多重用法語句來完成的,每個語句隨後添加了不同特徵的名稱。所有特徵的方法和屬性將在同類中可用。如果不同性狀中的方法或屬性之間存在命名衝突,則可以使用代替和運算符來解決它。

>

>特徵可以注入服務嗎?

特徵本身不能直接注入服務,因為它們不是類,也不支持構造函數注入。但是,您可以將服務注入使用特徵的類。特徵的方法然後可以通過課程訪問這些服務。

>特徵可以覆蓋學說實體中的方法嗎?通過定義特徵中的方法,其名稱與類中的方法相同。當在類的對像上調用該方法時,特徵中的版本將被代替類中的版本。

>

我可以將特質與繼承結合使用嗎? ,您可以將特徵與繼承結合使用。類可以從父班繼承,也可以使用一個或多個特徵。父類的方法和屬性和特質都將在類中可用。如果父母類中的方法或屬性之間存在命名衝突,則特徵中的版本將被使用。特徵為代碼重用和靈活性提供了強大的工具,它們也有一些局限性和潛在的缺點。一個限制是,不能自行實例化特徵 - 它們只能在班級中使用。同樣,如果多個特徵定義了具有相同名稱的方法,則可能需要手動解決命名衝突。過度使用性狀也可能導致難以理解和維護的代碼,因此應明智地使用它們。

我如何測試使用特徵的學說實體?

>測試使用特徵的學說實體類似於測試常規學說實體。您可以創建實例化實體並調用其方法的單元測試,以檢查其表現是否如預期。如果特徵提供其他方法,則可以以相同的方式測試這些方法。如果特徵覆蓋了實體中的方法,則應同時測試該方法的原始版本(通過在不使用特徵的實體上測試它)和覆蓋版本(通過在使用特徵的實體上測試它) 。

>我可以在具有Symfony的學說實體中使用特徵嗎? Symfony的學說整合支持在實體中使用特徵。您可以定義自己的特徵,在您的實體中使用它們,並在與您的實體合作時會識別並使用它們。

>

我如何調試學說實體中特徵的問題?學說實體中的特徵類似於調試常規學說實體的問題。您可以使用Xdebug和var_dump()之類的工具來檢查實體的狀態,並查看它們的方法和屬性。如果方法不按預期的方式行事,則可以檢查該方法是在實體本身,性狀還是在父級中定義的,並相應地調試。

以上是在學說實體中使用特徵的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板