Я перенес свои сообщения в собственный блог, потому что Medium становится все менее и менее удобным для читателей (платный доступ, невозможность выделить код и т. Д.). Чтобы прочитать эту статью в более приятном и дружественном контексте, прочтите ее в моем личном блоге и подписывайтесь на меня в Twitter, чтобы получать уведомления!
Https://titouangalopin.com/using-traits-to-compose-your-doctrine-entities/
Черты были введены в PHP 5.4 (6 лет назад) как способ составлять классы, не полагаясь на наследование (в отличие от возможности расширять несколько классов, как в C ++). Эта функция PHP уже сама по себе активно используется во многих фреймворках.
Однако есть особый случай, когда черты характера проявляются еще больше: сущности доктрины. В этой быстрой статье (август;)) я хотел бы поговорить о том, как черты могут быть чрезвычайно полезны для создания ваших сущностей Doctrine, особенно при использовании расширений Doctrine.
Использование черт в ваших сущностях
Сущность, являющаяся стандартным классом PHP, вполне может использовать черты для определения дополнительных свойств. Более того, Doctrine может обрабатывать аннотации к свойствам признаков так же, как если бы они были свойствами внутри самой сущности.
Мы можем использовать это для создания многократно используемых частей сущностей. Например, у большинства моих сущностей есть ID и UUID (как я обсуждал в соответствующей статье). Используя трейт, я могу легко поделиться этими двумя полями со всеми своими сущностями:
class Project { use EntityIdTrait; // ... } trait EntityIdTrait { /** * The unique auto incremented primary key. * * @var int|null * * @ORM\Id * @ORM\Column(type="integer", options={"unsigned": true}) * @ORM\GeneratedValue */ protected $id; /** * The public primary identity key. * * @var UuidInterface * * @ORM\Column(type="uuid", unique=true) */ protected $uuid; public function getId(): ?int { return $this->id; } public function getUuid(): UuidInterface { return $this->uuid; } }
Использование трейтов для удобного использования расширений Doctrine
Расширения Doctrine - это набор расширений, разработанных, чтобы помочь вам с общими задачами, связанными с сущностями, такими как ярлыки, временные метки и т. Д. Используя трейты, можно упростить использование этих расширений.
EntityNameTrait
Например, я создал черту, определяющую общее поле name и связанный с ним slug, который будет автоматически заполняться расширением Sluggable Doctrine. Кроме того, он определяет метод __toString для моих сущностей с использованием имени.
use Doctrine\ORM\Mapping as ORM; use Gedmo\Mapping\Annotation as Gedmo; use Symfony\Component\Validator\Constraints as Assert; trait EntityNameTrait { /** * @var string|null * * @ORM\Column(length=100) * * @Assert\NotBlank * @Assert\Length(max=100) */ private $name; /** * @var string|null * * @Gedmo\Slug(fields={"name"}) * * @ORM\Column(length=100, unique=true) */ private $slug; public function __toString() { return $this->name; } public function getName(): ?string { return $this->name; } public function setName(?string $name): void { $this->name = $name; } public function getSlug(): ?string { return $this->slug; } public function setSlug(?string $slug): void { $this->slug = $slug; } }
EntityTimestampableTrait
В той же идее я создал трейт для использования расширения Doctrine Timestampable для автоматического сохранения даты создания и даты последнего обновления любой сущности.
use Doctrine\ORM\Mapping as ORM; use Gedmo\Mapping\Annotation as Gedmo; trait EntityTimestampableTrait { /** * @var \DateTime * * @ORM\Column(type="datetime") * * @Gedmo\Timestampable(on="create") */ protected $createdAt; /** * @var \DateTime * * @ORM\Column(type="datetime") * * @Gedmo\Timestampable(on="update") */ protected $updatedAt; public function getCreatedAt(): \DateTime { return $this->createdAt; } public function getUpdatedAt(): \DateTime { return $this->updatedAt; } public function setUpdatedAt(\DateTime $updatedAt) { $this->updatedAt = $updatedAt; } }
EntitySoftDeletableTrait
Наконец, эта черта использует расширение SoftDeletable для хранения в базе данных некоторых важных сущностей, при этом обрабатывая их как скрытые для приложения.
use Doctrine\ORM\Mapping as ORM; trait EntitySoftDeletableTrait { /** * @var \DateTime|null * * @ORM\Column(type="datetime", nullable=true) */ private $deletedAt; public function getDeletedAt(): ?\DateTime { return $this->deletedAt; } public function isDeleted(): bool { return $this->deletedAt instanceof \DateTimeInterface; } public function recover() { $this->deletedAt = null; } }
Я обычно не использую другие расширения, поэтому я не создал для них трейт. Однако это довольно просто сделать и может быть чрезвычайно полезно: не сомневайтесь, создайте его самостоятельно :)!
Есть ли у вас отзывы / идеи? Не стесняйтесь комментировать!