在另一个 class 中使用 class 的最佳方式

Best way to use a class inside another class

我创建了这个 class 从数据库中获取 post 的所有数据。

class Post {
    private $id;
    protected $conn;
    public $data;

    function __construct(\mysqli $conn) {
        $this->conn = $conn;
    }

    public function getId() {
        return $this->id;
    }

    public function getConnection() {
        return $this->conn;
    }

    public function getPost() {
        $query1 = $this->getConnection()->query("SELECT * FROM posts WHERE id=" . $this->id);

        if ($query1->num_rows == 1) {
            $this->data = $query1->fetch_object();
            return $this->data;
        }
    }

    public function setId($id) {
        $this->id = (int)$id;
    }
}

除了 post,我还需要获取创建 post 的用户的所有数据。我有三种方法可以做到这一点:

1) 通过在 Post class.

中调用用户 class
    public function getPost() {
        $query1 = $this->getConnection()->query("SELECT * FROM posts WHERE id=" . $this->id);

        if ($query1->num_rows == 1) {
            $this->data = $query1->fetch_object();

            // Initiating User class
            $user = new User($this->getConnection());
            $user->setUserId($this->data->user_id);
            $this->data->user = $user->getUserInfo();

            return $this->data;
        }
    }


2) 通过使用用户 class.

扩展 Post class
class Post extends User {
    ....

然后从用户调用方法class

    public function getPost() {
        $query1 = $this->getConnection()->query("SELECT * FROM posts WHERE id=" . $this->id);

        if ($query1->num_rows == 1) {
            $this->data = $query1->fetch_object();

            // Calling methods from the User class
            $this->setUserId($this->data->user_id);
            $this->data->user = $this->getUserInfo();

            return $this->data;
        }
    }


3) 通过创建用户特征并在 Post class.

中使用它
class Post {
    use UserTrait;
    ....

然后从用户特征调用方法

    public function getPost() {
        $query1 = $this->getConnection()->query("SELECT * FROM posts WHERE id=" . $this->id);

        if ($query1->num_rows == 1) {
            $this->data = $query1->fetch_object();

            // Calling methods from the User trait
            $this->setUserId($this->data->user_id);
            $this->data->user = $this->getUserInfo();

            return $this->data;
        }
    }


在这 3 种方法中,哪种方法在依赖注入、性能和代码清洁度方面最好?

这完全取决于您要继续做些什么。如果您打算使用其他 classes 的永久方法,那么使用扩展的 class 是更好的选择。如果您只需要另一个 class 的一部分,那么只需调用 class 及其方法即可。

注意:扩展 class 的行为与单个 class 相同。如果方法和函数的名称相同,可能会发生很多冲突。

我认为这取决于您代码的其他方面。就我个人而言,我只会扩展 class 用户,因为我认为在这种特殊情况下不需要使用特征。

这里有一篇关于在 PHP 中使用 Traits 的有用文章 - Using Traits in PHP 5.4

这个问题可能会被否决,因为你是在征求意见,但我会投入我的两分钱。

您基本上是在构建自己的基本 ORM。在那个 ORM 中,你正在处理实体。不同的实体应该由不同的类(模型)处理,并且底层数据库table和模型之间应该有1:1等价。

您的实体之间存在关系。你的 Post 实体有一个作者,它应该是用户实体的一个实例。但是,您不会说 post table 和用户 table 之间的关系意味着它们可以由相同的模型或父模型的不同风格表示。

如果您使用完整的 ORM(Doctrine、Propel、RedbeanPHP),您会看到 Post 作者这样的关系意味着,当使用 getById() 这样的方法时(在您的情况下getPost() ) 默认情况下,检索到的 Post 实体将继续实例化每个依赖实体。

在您的情况下,ORM 不会为您提供 $this->data->user_id,而是为您提供一个嵌套的 $this->data->user 对象,这样您就不必自己处理它。

因此,如果您认为现在使用 ORM 还为时过早,第一种方法在时机成熟时更容易维护和迁移。

不相关的意见

此时,要获得 post 您需要做的信息

$post = new Post($conn);
$post->setId($postid);
$postdata = $post->getPost();

如果您更改了构造函数并添加了 getById() 方法,这样

function __construct(\mysqli $conn) {
    $this->conn = $conn;
    return $this;
}

public function getById($id) {
     $this->setId($id);
     return $this->getPost();
}

您可以改为在一行中检索 post 数据

$postdata=(new Post($conn))->getById($postid);