Zend framework 如何使用Zend Framework在域中建立多表继承?
我有一个数据库结构,它有一个Person表,其中包含诸如name、email、company\u id、personType等字段。因为不是所有的人都必须是系统用户,所以我有一个单独的表user,它为系统中的用户定义用户名和密码 我有以下代码来定义Person表的表数据网关:Zend framework 如何使用Zend Framework在域中建立多表继承?,zend-framework,orm,multiple-inheritance,Zend Framework,Orm,Multiple Inheritance,我有一个数据库结构,它有一个Person表,其中包含诸如name、email、company\u id、personType等字段。因为不是所有的人都必须是系统用户,所以我有一个单独的表user,它为系统中的用户定义用户名和密码 我有以下代码来定义Person表的表数据网关: class Model_Table_Person extends Zend_Db_Table_Abstract { protected $_name = 'person'; protected $_prim
class Model_Table_Person extends Zend_Db_Table_Abstract
{
protected $_name = 'person';
protected $_primary = 'person_id';
protected $_referenceMap = array(
'Company' => array(
'columns' => 'company_id',
'refTableClass' => 'Company',
'refColumns' => 'id'
),
'Store' => array(
'columns' => 'store_id',
'refTableClass' => 'Store',
'refColumns' => 'id'
)
);
public function findByPersonType(string $personType)
{
$where = $this->getAdapter()->quoteInto('personType = ?', $personType);
return $this->fetchAll($where);
}
}
此代码为Person定义域对象:
class Model_Person
{
protected static $_gateway;
protected $_person;
public static function init()
{
if(self::$_gateway == null)
{
self::$_gateway = new Model_Table_Person();
}
}
public static function get(string $searchString, string $searchType = 'id')
{
self::init();
switch($searchString)
{
case 'id':
$row = self::$_gateway->find($id)->current();
break;
}
return self::factory($row);
}
public static function getCollection(string $searchString, string $searchType = null)
{
self::init();
switch($searchType)
{
case 'userType':
$row = self::$_gateway->findByPersonType($searchString);
break;
default:
$personRowset = self::$_gateway->fetchAll();
break;
}
$personArray = array ();
foreach ($personRowset as $person)
{
$personArray[] = self::factory($person);
}
return $personArray;
}
public function getCompany()
{
return $this->_person->findParentRow('Company');
}
public function getStore()
{
return $this->_person->findParentRow('Store');
}
protected static function factory(Zend_Db_Table_Row $row)
{
$class = 'Model_Person_' . ucfirst($row->personType);
return new $class($row);
}
// protected constructor can only be called from this class, e.g. factory()
protected function __construct(Zend_Db_Table_Row $personRow)
{
$this->_person = $personRow;
}
}
最后,我为用户提供了另一个表数据网关:
class Model_Table_User extends Zend_Db_Table_Abstract
{
protected $_name = 'user';
protected $_primary = 'person_id';
public function findByUserName()
{
}
}
还有一个扩展Model_Person表的基本类,如下所示:
class Model_User extends Model_Person
{
public function login()
{
}
public function setPassword()
{
}
}
如何正确地扩展“Model\u User”类(它为除一个以外的所有其他类型的用户提供基本类型)以使用映射到一个表的“Model\u Person”类函数,同时也将实际的“Model\u User”函数映射到第二个表?这是PHP的一个巨大弱点(在5.3.0之前)--缺乏对政府的支持 也就是说,当一个静态方法(如
get()
调用另一个静态方法(如init()
)时,它总是使用该类中定义的init()
方法。如果子类定义了一个替代方法init()
,并调用get()
,希望它调用被重写的init()
,则不会发生这种情况
class A
{
static $var = null;
static function init() { self::$var = 1234; }
static function get() { self::init(); }
}
class B extends A
{
static function init() { self::$var = 5678; }
}
B::get();
print B::$var . "\n";
这将打印“1234”,而您可能希望它打印“5678”。这就好像A::get()
不知道它是类B
的一部分。解决方法是必须将get()
方法的实现复制到子类中,即使它与超类没有什么不同这非常不令人满意
PHP 5.3.0试图解决此问题,但您必须在get()
中对其进行稍微不同的编码:
PHP5.3.0目前仍处于alpha版本
有几种可能的解决办法:
- 不要将
子类化为Person
,而是将login和password属性添加到User
类中。如果这些属性为NULL,则它是非用户,函数Person
和login()
应该注意这一点,并抛出异常或返回false或其他内容setPassword()
- 每个子类型使用不同的
方法:get()
,getUser()
,等等。每种方法都将初始化各自的表对象getPerson()
function get() {
static::init();
}