首页 > 后端开发 > php教程 > 在学说实体中使用特征

在学说实体中使用特征

Jennifer Aniston
发布: 2025-02-19 09:20:11
原创
581 人浏览过

在学说实体中使用特征

钥匙要点

    自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
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板