在另一个 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);
我创建了这个 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.
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);