Php 实体类的用途和好处是什么?

Php 实体类的用途和好处是什么?,php,class,oop,entity,Php,Class,Oop,Entity,我经常遇到如下代码(参考) TicketMapper.php class TicketMapper extends Mapper { public function getTickets() { $sql = "SELECT t.id, t.title, t.description, c.component from tickets t join components c on (c.id = t.component_id)

我经常遇到如下代码(参考)

TicketMapper.php

class TicketMapper extends Mapper
{
    public function getTickets() {
        $sql = "SELECT t.id, t.title, t.description, c.component
            from tickets t
            join components c on (c.id = t.component_id)";
        $stmt = $this->db->query($sql);
        $results = [];
        while($row = $stmt->fetch()) {
            $results[] = new TicketEntity($row);
        }
        return $results;
    }
    /**
     * Get one ticket by its ID
     *
     * @param int $ticket_id The ID of the ticket
     * @return TicketEntity  The ticket
     */
    public function getTicketById($ticket_id) {
        $sql = "SELECT t.id, t.title, t.description, c.component
            from tickets t
            join components c on (c.id = t.component_id)
            where t.id = :ticket_id";
        $stmt = $this->db->prepare($sql);
        $result = $stmt->execute(["ticket_id" => $ticket_id]);
        if($result) {
            return new TicketEntity($stmt->fetch());
        }
    }
    public function save(TicketEntity $ticket) {
        $sql = "insert into tickets
            (title, description, component_id) values
            (:title, :description, 
            (select id from components where component = :component))";
        $stmt = $this->db->prepare($sql);
        $result = $stmt->execute([
            "title" => $ticket->getTitle(),
            "description" => $ticket->getDescription(),
            "component" => $ticket->getComponent(),
        ]);
        if(!$result) {
            throw new Exception("could not save record");
        }
    }
}
tickettenty.php

class TicketEntity
{
    protected $id;
    protected $title;
    protected $description;
    protected $component;
    /**
     * Accept an array of data matching properties of this class
     * and create the class
     *
     * @param array $data The data to use to create
     */
    public function __construct(array $data) {
        // no id if we're creating
        if(isset($data['id'])) {
            $this->id = $data['id'];
        }
        $this->title = $data['title'];
        $this->description = $data['description'];
        $this->component = $data['component'];
    }
    public function getId() {
        return $this->id;
    }
    public function getTitle() {
        return $this->title;
    }
    public function getDescription() {
        return $this->description;
    }
    public function getShortDescription() {
        return substr($this->description, 0, 20);
    }
    public function getComponent() {
        return $this->component;
    }
}
我当前的做法不使用实体类,我的映射器方法只返回一个stdClass,如下所示:

class TicketMapper extends Mapper
{
    public function getTickets() {
        $sql = "...";
        $stmt = $this->db->query($sql);
        return $stmt->fetchAll(PDO::FETCH_OBJ);
    }
    public function getTicketById($ticket_id) {
        $sql = "...";
        $stmt = $this->db->prepare($sql);
        $result = $stmt->execute(["ticket_id" => $ticket_id]);
        return $stmt->fetch();  //Assuming my PDO is configured to return an object only
    }
    public function save($ticket) {/* no change */}
}

为什么数据库结果经常包装在某个实体类中?是否有任何标准可以决定是否这样做?

封装:类是一个有用的包,包含代码和相关数据,与其他所有内容隔离。这使得它更容易移动,而无需搜索精确的变量,也不会与现有代码/数据发生冲突

当然,类还有其他用途,但在像PHP这样的脚本环境中,我认为最大的优势就是它

代码重用

继承权

易于维护

等等。做一些研究学习这是一件有趣的事情

关键是充当业务逻辑和存储之间的持久层。它在实体对象中填充或存储数据

这些实体有几个目标:

  • 封装:您能够跟踪和控制实体包含的数据的访问和更改方式

  • 验证:确保实体的状态与业务规则相匹配,并能够检测实体是否已进入(或即将进入)无效状态

  • 契约:您可以使用类型提示来定义哪些其他模块(类、函数)可以使用此实体,以及它可以接受哪些类型的对象作为参数。您还可以选择定义此实体的替代项必须实现的接口

  • 行为:实体通常会有关联的行为(或业务逻辑),例如:
    $article->markAsApproved()
    操作将不是一个简单的设置程序,而是对状态进行原子更改

至于标准。。。好。。。“您是否使用OOP”将是最接近的一个。
stdClass
只是一个美化的数组,没有任何行为


您可能应该观看。

谢谢gmbc。我肯定看到了类、通过继承简化脚本和封装的好处,但除了几个getter和setter之外,我从未看到用这些实体类实现的任何功能,这让我质疑为什么要费心使用它们。感谢tereško,我确实看到了验证和契约的一些好处(然而,我认为应该由服务而不是实体负责验证)。刚才看到你的行为目标弹出,我想这是有道理的。你总是这样做,除非你有令人信服的理由不这样做吗?现在就看讲座。验证是一个非常模糊的术语:(因为它实际上涵盖了不同类型的内容。例如,“电子邮件地址看起来是否正确”将由实体验证,而“有人已经注册了此电子邮件”将在映射器中完成(因为这将是一项数据完整性检查)。以及类似于“您可以使用购物车中的0个项目开始结帐”之类的内容将是由服务检查的内容。