PHP 构造函数包含用于构建对象的数据库查询,好/坏?
Posted
技术标签:
【中文标题】PHP 构造函数包含用于构建对象的数据库查询,好/坏?【英文标题】:PHP Constructor Containing Database Query to build object, good/bad? 【发布时间】:2013-08-02 05:27:11 【问题描述】:在类的构造函数中进行数据库查询以便在创建它的新实例时加载它是不好的做法吗?
class Home
private $home_id = null;
private $home_name = null;
private $home_number = null;
private $home_street = null;
function __construct($home_id)
$do_query = $mysql_con->query("SELECT * FROM home WHERE home_id = '$home_id'");
while ($home_data = $do_query->fetch_assoc())
// Set all of the items in the object
$this->home_id = $home_data["home_id"];
$this->home_name = $home_data["home_name"];
$this->home_number = $home_data["home_number"];
$this->home_street = $home_data["home_street"];
之前有人告诉我,在构造函数中创建一个构建对象的查询可能是不好的做法。
如果这是不好的做法,为什么是不好的做法? 有什么替代方案?【问题讨论】:
$mysql_con
定义在哪里?
【参考方案1】:
您的Home
类是一个域对象,理想情况下这些对象不应该知道它们是如何被持久化的。
分离关注点可以提高灵活性。这也称为数据映射器模式。
class Home
public $home_id;
public $home_name;
public $home_number;
public $home_street;
interface HomeMapperInterface
public function get($id);
class HomeMapper implements HomeMapperInterface
public function __construct($db)
$this->db = $db;
public function get($id)
$query = $this->db->query(...);
if (($row = $do_query->fetch_assoc()) === false)
throw new RecordNotFoundException();
$home = new Home;
$home->home_id = $row['home_id'];
// ...
return $home;
使用它:
$mapper = new HomeMapper($db);
$home = $mapper->get(123);
您可以通过使用标识符映射来改进这一点,以避免将相同的记录两次加载到不同的对象中。
顺便说一句,这只是部分数据映射器;它还可以用于更新、插入和删除数据库中的对象。
【讨论】:
【参考方案2】:存储库模式是帮助缓解此问题的有用工具,请查看之前的 SO 讨论。
Proper Repository Pattern Design in php?
【讨论】:
【参考方案3】:如果你小心的话,这不一定是坏习惯。例如,查询失败时会发生什么?构造函数是返回一个半生不熟的对象还是抛出异常?抛出异常被认为更好,因为对半构造对象进行操作可能会导致难以预测的错误。
另一个问题是性能:数据库查询可能是一项昂贵的操作。有些人可能会对构造函数需要很长时间才能完成感到惊讶,但如果它有明确的记录,应该没有问题。
另一个性能问题是批处理:如果您必须使用这样的设计从数据库中获取多个对象,那么您必须对数据库进行许多单独的查询,而您只能创建一个并根据结果构造对象。
【讨论】:
以上是关于PHP 构造函数包含用于构建对象的数据库查询,好/坏?的主要内容,如果未能解决你的问题,请参考以下文章
PHP使用组件构建自己的PHP框架查询构造器进行数据库操作 DB