我正在考虑这样的问题…假设我们有一个类Person:
class Person {
private $iPersonId;
private $sName;
private $sLastName;
private $rConn;
public function __construct($rConn, $iPersonId) {
$this->rConn = $rConn;
$this->iPersonId = $iPersonId;
}
public function load() {
// load name and last name using the $rConn object and $iPersonId
}
}
现在我们想对很多人执行一些操作,所以我们写了一个新类:
class People {
private $aPeople = array();
public function addPerson(Person $oPerson) {
// ...
}
public function loadPeople() {
// PROBLEM HERE //
}
}
现在有两个问题:1. Person和People有相同的加载接口(function load()),但如果我想迭代People中的$ People来加载他们的数据,那么这将导致maaaaany查询,如:
SELECT * FROM people WHERE id = 1
SELECT * FROM people WHERE id = 2
SELECT ......
.....
....
如果想加载1000个,那么就会出现boom:)。
我如何设计在一个查询中加载所有用户的代码?(在)
- 我必须在我添加到People中的每个Person对象中保持使用依赖注入。这是违反DRY规则,只是不好看。
那么亲爱的用户,什么是更好的方法来设计这个代码?
我建议在People中使用静态方法来加载大量的人。这还需要您重写构造函数,或者添加另一个方法来初始化其他数据。
class Person {
protected $_data
protected $rConn;
public function __construct($rConn, $iPersonId) {
$this->rConn = $rConn;
$this->_data = array();
$this->_data['id'] = $iPersonId;
}
public function load() {
// load name and last name using the $rConn object and $iPersonId
}
// under the assumption, that $rConn is a mysqli connection
// if not rewrite the specific section
// also there is no injection protection or error handling in here
// this is just a workflow example, not good code!
public static function loadPeople($ids) {
$res = $rConn->query("select * from people where id in (" . implode(',', $ids) . ")");
$people = array();
while ($row = $res->fetch_assoc()) {
$p = new People($rConn, $row['id']);
$p->setData($row);
$people[] = $p;
}
$res->free();
return $people;
}
public function setData($data) {
foreach ($data as $key => $value {
$this->_data[key] = $value;
}
}
}
如果像Symfony2 (http://symfony.com/doc/2.0/book/service_container.html)那样构建服务,只需添加方法即可。在"person"上使用"load()"听起来不太对。它自己装载什么?让对象或实体访问数据库也是一种不好的做法,这会导致不必要的依赖关系。
- 你的实体或对象永远不应该有一个函数来加载自己,这是不好的做法。让其他东西来管理实体或对象。
- 不要让依赖关系引起混乱,保持一个对象自己的目的。PersonEntity不应该知道任何关于数据库连接或EntityManager的信息
- 构建你的代码,这样你就可以把它移动到另一个项目,而不会破坏Composer。http://getcomposer.org/
的示例
class PeopleService
{
private $em;
/**
* @param EntityManager $em
*/
public function __construct(EntityManager $em)
{
$this->em = $em;
}
/**
* @param int $id
* @return Person
*/
public function loadPerson($id)
{
// do something and return 1 person
return $this->em->find('MyBundleNamspace:Person', $id);
}
/**
* @return array of Person objects
*/
public function loadPeople()
{
// do something and return an array with persons
}
}