Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 在OOP中编写质量数据模型_Php_Oop - Fatal编程技术网

Php 在OOP中编写质量数据模型

Php 在OOP中编写质量数据模型,php,oop,Php,Oop,我一直在努力为我的应用程序编写好的数据模型。让我们以人作为数据的一个例子。如何将Person类与People类进行不可重复但可重用的分离?对于这两个类,必须定义两次表及其联接表似乎是完全错误的 class Person extends CommonModel { protected static $table = 'people'; protected static $join = array('city' => 'city.id = people.city_id');

我一直在努力为我的应用程序编写好的数据模型。让我们以人作为数据的一个例子。如何将Person类与People类进行不可重复但可重用的分离?对于这两个类,必须定义两次表及其联接表似乎是完全错误的

class Person extends CommonModel {
   protected static $table = 'people';
   protected static $join  = array('city' => 'city.id = people.city_id');

   public function __construct($id) {
      // Initialize stuff
   }

   public function fetch($id) {
      // Return person with id $id
   }

   public function isVeryTall() {
      // Return boolean
   }
}

class People extends CommonModel {
   protected static $table = 'people';
   protected static $join  = array('city' => 'city.id = people.city_id');

   public function __construct($id) {
      // Initialize stuff
   }

   public function fetch() {
      // Return all persons
   }
}
但如果我将它们加入到一个类中,那么当返回一个人员列表时,某些方法(仅在单个人员的上下文中才有意义)将不可用。例如,只有在表示一个人的对象上调用isVeryTall方法时,它才真正起作用。但是如果我调用了fetchPeople方法,那么我的isVeryTall方法将在返回的对象中可用,并且它将没有意义,实际上它甚至可能无法正常工作

class Person extends CommonModel {

   protected static $table = 'people';
   protected static $join  = array('city' => 'city.id = people.city_id');

   public function __construct($id) {
      // Return one person
   }

   public function fetchPeople() {
      // Returns all people 
   }

   public function isVeryTall() {
      // Return boolean
   }
}
另一个问题是,我如何实现返回人员列表的方法,以返回人员对象,而不仅仅是数组?我是否需要手动循环所有行,然后将它们实例化为对象

public function fetchPeople() {
   $people = $this->fetchAll();
   foreach($people as $id => $person) {
      $people[$id] = new Person($person);
   }
   return $people;
}

我不会将特定于实现的持久性代码放在域类中的数据库中。把它们分开。然后你可以有一个Person类来为一个人做你需要的事情。对于Person对象的集合,如果组中存在与持久性无关的特定方法,则可以定义一个新类,或者可以使用内置的集合类型数组之一

有许多方法可以将持久性数据库代码分开。我使用存储库模式。我使用在域对象和持久性策略数据库之间进行转换所需的方法创建了一个类。方法如下:

getPerson(PersonCriteria $pc);
getPeople(PersonCriteria $pc);
savePerson(Person $p);
deletePerson($personID);
etc()...
你最终要做的是为你需要的很多零件重新制作轮子。来自解决最后一个问题的关联和集合。您必须从关联和集合构造数据库查询。您将创建一个标准库的某些部分,而这可能不是您的目标。我会通过pear库查看那里的标准ORM,或者查看。还有一些是教条和推进

如果您想使用自己的方法,并且希望继续使用第一种方法,并设置一个collections类来使用where子句对更大批量的数据进行分页和查询

所以

//在基类db中 //过滤器将是分页和成对的,用于where子句过滤 公共函数获取$filters{ 返回$this->query$filters } // ... 在你的孩子班上。。使用现有的联接和表属性。。我建议搬家 //这些关联被扩展到另一个类中,但正如您所看到的,这些关联的细节可以继续下去 公共函数fetchPeople$limit=10,$page=1{ $associations={'table'=>$this->table'join'=>$this->join} $people=$this->db->fetcharray'limit'=>$limit,'page'=>$page,$associations; foreach$people作为$id=>$person{ $people[$id]=新人$Person; } 返回$people; }
我不知道你所说的与持久性无关的特定方法是什么意思。你能给我举一个例子,说明一个与持久性无关的方法吗?我有一个相对简单的想法,基本上只是一个我有权看到的人的列表,例如我的组中的人,这是一个在构造函数中根据我自己的用户组形成的条件。我不知道你是否认为这是持久的。在最初的例子中,FoTCHEVER是持久性代码,而ISVY不是。对于权限内容,我的域对象中有权限$permissionName和getGroupNumber。我在criteria对象中有权限和组ID作为选项。创建criteria对象是为了与持久性层通信您需要哪些对象。内容通常转换为WHERE子句,但使用域语言编写,而不是使用SQL编写,以避免域中存在特定于持久性实现的代码。希望有帮助。