Zend Framework1-Zend_Db_Table

5、Zend_Db_Table

Zend_Db_Table是Zend Framework的表模块,它通过zend_db_adapter连接到数据库,为数据库模式检查表对象,并对该表进行操作和查询。

首先需要为抽象类zend_db_table(ares注:该类为抽象类,所以不能直接实例化,只能先继承该类。然后实例化子类)设定一个默认对数据库adapter;

除非你指定其他类型数据库adapter,否则,所有的zend_db_table类实例都会使用默认adapter。

<?php
// 建立一个 adapter
require_once 'Zend/Db.php';
$params = array (
    'host'     => '127.0.0.1',
    'username' => 'malory',
    'password' => '******',
    'dbname'   => 'camelot'
);
$db = Zend_Db::factory('PDO_MYSQL', $params);
// 为所有的Zend_Db_Table对象设定默认的adapter
require_once 'Zend/Db/Table.php';
Zend_Db_Table::setDefaultAdapter($db);
?>

接下来,我们假定数据库中存在一个名为”round_table”的表。要对该表使用zend_db_table,只需继承zend_db_table类创建一个名为RoundTable的新类。

然后我就可以通过该类在数据库中的round_table表中检查,操作数据行并且取得数据结果。

<?php
class RoundTable extends Zend_Db_Table {}
$table = new RoundTable();
?>      

5.1.1表名和主键

默认情况下,zend_db_table类会将其类名当作数据库中表名(大小写不同 的地方需要添加"_")。

例如,一个名为SomeTableName的zend_db_table类在数据库中就对应表”some_table_name”。假如不希望将类名与数据库表名以这种添加下划线的形式进行对应,可以在定义该类时对$_name进行重构。

<?php
class ClassName extends Zend_Db_Table
{
    // 默认表名为 'class_name'
    // 但是我们也可以对应其它表
    protected $_name = 'another_table_name';
}
?>

zend_db_table类默认字段”id”为表的主键(该字段最好为自增的,但并不是必须的)。假如该表的主键并不是名为”$id”,你可以在定义表实体类时对$_primary进行重构

<?php
class ClassName extends Zend_Db_Table
{
    // 默认主键为’id’
    // 但我们也可以设定其他列名为主键
    protected $_primary = 'another_column_name';
}
?>

你也可以通过表实体类中_setup()方法设定这些变量,但是需要确保在修改后再执行一次parent::_setup()方法.

<?php
class ClassName extends Zend_Db_Table
{
    protected function _setup()
    {
        $this->_name = 'another_table_name';
        $this->_primary = 'another_column_name';
        parent::_setup();
    }
}
?>

5.1.2插入数据

要在表中插入一行新数据,只需要将列名:数据的关联数组作为参数,调 用insert()方法即可。(zend framework)会自动对数据进行加引号处理,,并返回插入的最后一行的id值(注意:这里不同于 zend_db_adapter::insert方法,后者返回的是插入的行数)。

<?php
// INSERT INTO round_table
//     (noble_title, first_name, favorite_color)
//     VALUES ("King", "Arthur", "blue")

class RoundTable extends Zend_Db_Table {}

$table = new RoundTable();

$data = array(
    'noble_title' => 'King',
    'first_name'  => 'Arthur',
    'favorite_color' => 'blue',
)

$id = $table->insert($data);
?>   

5.1.3更新数据

要修改表中的任意行数据,我们可以设定一个列名:数据的关联数组作为参数,调 用update()方法,同是通过一个where条件从句来决定需要改变的行。该方法将会 修改表中数据并返回被修改的行数。

(Zend frameword)将会自动对修改对数据进行加引号处理,但是这种检查不包括 条件分句,所以你需要使用该表的zend_db_adapter对象完成该工作。

<?php
// UPDATE round_table
//     SET favorite_color = "yellow"
//     WHERE first_name = "Robin"

class RoundTable extends Zend_Db_Table {}

$table = new RoundTable();
$db = $table->getAdapter();

$set = array(
    'favorite_color' => 'yellow',
)

$where = $db->quoteInto('first_name = ?', 'Robin');

$rows_affected = $table->update($set, $where);
?>

5.1.4Deleting Rows

要删除表中的数据,我们可以调用delete()方法,同时通过一个where条件分句来决定需要删除的行。该方法将会返回被删除的行数。

(zend framework)不会对条件分句进行加引号处理,所以你需要使用该表 的zend_db_adapter对象完成该工作。

<?php
// DELETE FROM round_table
//     WHERE first_name = "Patsy"

class RoundTable extends Zend_Db_Table {}

$table = new RoundTable();
$db = $table->getAdapter();

$where = $db->quoteInto('first_name = ?', 'Patsy');

$rows_affected = $table->delete($where);
?>    

5.1.5根据主键查找数据

通过调用find()方法,可以使用主键值轻松地在表中检索数据。假如你只想要查询某一条数据,该方法将回返回一个zend_db_table_row对象,而当你想要查询多条记录时,将会返回一个zend_db_table_rowset对象。

<?php
class RoundTable extends Zend_Db_Table {}

$table = new RoundTable();

// SELECT * FROM round_table WHERE id = "1"
$row = $table->find(1);

// SELECT * FROM round_table WHERE id IN("1", "2", 3")
$rowset = $table->find(array(1, 2, 3));
?>    

5.1.6取回一条记录

虽然通过主键找到相应数据行是很便利的事情,但是在更多的时候,我们是通过其他一些非主键的条件来查找数据行的。zend_db_table提供了一个 fetchRow()方法可以实现这个功能。

我们可以通过一个where条件语句(和一个可选的order语句)调用fetchRow()方法,然后zend_db_tabel将会返回满足条件的第一行数据的zend_db_table_row对象。

注意,(zend framework) 将不会对where语句进行加引号处理,所以你需要 通过zend_db_adapter进行数据处理。

<?php
// SELECT * FROM round_table
//     WHERE noble_title = "Sir"
//     AND first_name = "Robin"
//     ORDER BY favorite_color

class RoundTable extends Zend_Db_Table {}

$table = new RoundTable();
$db = $table->getAdapter();

$where = $db->quoteInto('noble_title = ?', 'Sir')
       . $db->quoteInto('AND first_name = ?', 'Robin');

$order = 'favorite_color';

$row = $table->fetchRow($where, $order);
?>   

5.1.7取回多条记录

假如需要一次检索多条记录。可以使用fetchAll()方法,和使用fetchRow()方法类似,该方法不仅仅可以设定where和order分句,也可以设定limit-count和limit-offset值来限制返回的结果数。

执行该方法后,把选择的结果作为一个 Zend_Db_Table_Rowset对象返回。注意,(zend framework) 将不会对where语句进行加引号处理,所以你需要 通过zend_db_adapter进行数据处理。

<?php
class RoundTable extends Zend_Db_Table {}

$table = new RoundTable();
$db = $table->getAdapter();

// SELECT * FROM round_table
//     WHERE noble_title = "Sir"
//     ORDER BY first_name
//     LIMIT 10 OFFSET 20

$where = $db->quoteInto('noble_title = ?', 'Sir');
$order = 'first_name';
$count = 10;
$offset = 20;

$rowset = $table->fetchAll($where, $order, $count, $offset);
?>

5.1.8Adding Domain Logic

作为Zend Framework的表模块,Zend_Db_Table将它自己很好的封装到独特的domain logic下。例如,你可以重载insert()和update()方法,以实现在数据更改提交前的操作和验证。

<?php
class RoundTable extends Zend_Db_Table
{
    public function insert($data)
    {
        // 添加一个时间戳
        if (empty($data['created_on'])) {
            $data['created_on'] = time();
        }
        return parent::insert($data);
    }

    public function update($data)
    {
        // 添加一个时间戳
        if (empty($data['updated_on'])) {
            $data['updated_on'] = time();
        }
        return parent::update($data);
    }
}
?>

类似的,你也可以设定自己的find()方法,通过主键外的其他字段来查询数据。

<?php
class RoundTable extends Zend_Db_Table
{
    public function findAllWithName($name)
    {
        $db = $this->getAdapter();
        $where = $db->quoteInto("name = ?", $name);
        $order = "first_name";
        return $this->fetchAll($where, $order);
    }
}
?>


5.2、Zend_Db_Table_Row

Zend_Db_Table_Row是Zend Framework的行数据网关。

通常来说,你不可以自己实例化Zend_Db_Table_Row,,而是通过调用Zend_Db_Table::find()方法或者Zend_Db_Table::fetchRow()方法将Zend_Db_Table_Row作为 结果数据返回过来。

一旦你得到来一个Zend_Db_Table_Row对象,你可以修改记录值(体现为类的属性)然后 调用save()方法可以将更改保存到原表上。

5.2.1取回一条记录

首先,需要实例化一个Zend_Db_Table类。

<?php
// 设置一个 adapter
require_once 'Zend/Db.php';
$params = array (
    'host'     => '127.0.0.1',
    'username' => 'malory',
    'password' => '******',
    'dbname'   => 'camelot'
);

$db = Zend_Db::factory('PDO_MYSQL', $params);

// 为所有的Zend_Db_Table对象设置默认adapter
require_once 'Zend/Db/Table.php';
Zend_Db_Table::setDefaultAdapter($db);

// 连接到数据库中的某一个表
class RoundTable extends Zend_Db_Table {}
$table = new RoundTable();
?>

接下来,使用Zend_Db_Table::find()方法和主键进行查询,或者使 用Zend_Db_Table::fetchRow()方法查询。

得到的返回结果是一个Zend_Db_Table_Row 对象,该对象的属性名采用camelCaps的形式对应数据库中带下划线的表名。例如,表名若为first_name,那么类中的该属性则为firstName。

<?php
// 从表中取回的结果数据是一个Zend_Db_Table_Row对象
$row = $table->fetchRow('first_name = "Robin"');

// $row现在是一个带有多种公有属性的Zend_Db_Table_Row对象
// that map to table columns:

// $row->id = '3'
// $row->nobleTitle = 'Sir'
// $row->firstName = 'Robin'
// $row->favoriteColor = 'yellow'

?>  

5.2.2修改数据

修改行数据是一件很轻松的事情:只需要按照常规的方法修改类属性。然后调用save()方法就将改变的结果保存到了数据表中。

<?php
// 连接到数据库中的表
class RoundTable extends Zend_Db_Table {}
$table = new RoundTable();

// 从表中取回的结果数据是一个Zend_Db_Table_Row对象
$row = $table->fetchRow('first_name = "Robin"');

// $row现在是一个带有多种公有属性的Zend_Db_Table_Row对象
// that map to table columns:
// $row->id = '3'
// $row->nobleTitle = 'Sir'
// $row->firstName = 'Robin'
// $row->favoriteColor = 'yellow'
// 改变favorite color字段,并且将变动存储到数据表中.
$row->favoriteColor = 'blue';'
$row->save();
?>

但是,你不能够修改主键的值。假如你试图进行改操作, Zend_Db_Table_Row将抛出一个异常.

<?php
// 连接到数据库中的表
class RoundTable extends Zend_Db_Table {}
$table = new RoundTable();

// fetch a record from the table as a Zend_Db_Table_Row object
$row = $table->fetchRow('first_name = "Robin"');

// 我们尝试修改主键值
try {
    $row->id = 5;
    echo "We should not see this message, as an exception was thrown.";
} catch (Zend_Db_Table_RowException $e) {
    echo $e->getMessage();
}
?> 

5.3、Zend_Db_Table_Rowset

Zend_Db_Table_Rowset是 Zend_Db_Table_Row对象集合的迭代器。

通常来说,你不可以自己实例化Zend_Db_Table_Rowset,而是通过调用Zend_Db_Table::find()方法或者fetchAll()方法将Zend_Db_Table_Rowset作为结果数据返回过来。

接下来就可以遍历Zend_Db_Table_Row对象集合并进行修改。

5.3.1取回结果集

首先,需要实例化一个Zend_Db_Table类,。

<?php
// 设置一个 adapter
require_once 'Zend/Db.php';
$params = array (
    'host'     => '127.0.0.1',
    'username' => 'malory',
    'password' => '******',
    'dbname'   => 'camelot'
);

$db = Zend_Db::factory('PDO_MYSQL', $params);

// 为所有的Zend_Db_Table对象设置默认
require_once 'Zend/Db/Table.php';
Zend_Db_Table::setDefaultAdapter($db);

// 连接数据库表
class RoundTable extends Zend_Db_Table {}
$table = new RoundTable();
?>

接下来,可以使用Zend_Db_Table::find()方法和多个键值,或者使用Zend_Db_Table::fetchAll()方法对数据库进行查询,

返回的结果是一个Zend_Db_Table_Rowset对象,可以通过该对象遍历结果集中的每一个Zend_Db_Table_Row对象。

<?php
// 从表中取回多条记录
$rowset = $table->fetchAll();

// $rowset现在是一个Zend_Db_Table_Rowset对象,该对象中每条记录就是一个Zend_Db_Table_Row对象
?>

5.3.2遍历结果集

Zend_Db_Table_Rowset实现了简单程序设计语言的迭代器接口,也就是说,,可以对Zend_Db_Table_Rowset 对象进行循环处理,就像使用foreach()函数处理数组一样。

使用这种方法取回的每一个值都是一个对应表中数据的Zend_Db_Table_Row对象,你可以查看,修改和保存该对象的属性(即表中的字段值)

<?php
// 连接到数据库中的表
class RoundTable extends Zend_Db_Table {}
$table = new RoundTable();

// 从表中取回多条记录
$rowset = $table->fetchAll();

// 显示所有的记录
foreach ($rowset as $row) {
    // $row 是一个 Zend_Db_Table_Row 对象
    echo "<p>" . htmlspecialchars($row->nobleTitle) . " "
       . htmlspecialchars($row->firstName) . "'s "
       . "favorite color is " . htmlspecialchars($row->favoriteColor)
       . ".</p>\n";

    // 更新我们显示改行的次数
    // (对应表中的"times_displayed"字段)
    $row->timesDisplayed ++;

    // 保存新记录.
    $row->save();
}
?>


5.4、Zend_Db_Table Relationships

在RDBMS中,表之间有着各种关系,有一多对应,多多对应等等。Zend框架提供了一些方法来方便我们实现这些关系。

下面是本文用的例子的关系定义:
  1. class Accounts extends Zend_Db_Table_Abstract
  2. {
  3.     protected $_name            = 'accounts';
  4.     protected $_dependentTables =  array ( 'Bugs' );
  5. }
  6.  
  7. class Products extends Zend_Db_Table_Abstract
  8. {
  9.     protected $_name            = 'products';
  10.     protected $_dependentTables = array ( 'BugsProducts' );
  11. }
  12.  
  13. class Bugs extends Zend_Db_Table_Abstract
  14. {
  15.     protected $_name            = 'bugs';
  16.  
  17.     protected $_dependentTables = array ( 'BugsProducts' );
  18.  
  19.     protected $_referenceMap    = array (
  20.         'Reporter' => array (
  21.             'columns'           => 'reported_by',
  22.             'refTableClass'     => 'Accounts',
  23.             'refColumns'        => 'account_name'
  24.         ),
  25.         'Engineer' => array (
  26.             'columns'           => 'assigned_to',
  27.             'refTableClass'     => 'Accounts',
  28.             'refColumns'        => 'account_name'
  29.         ),
  30.         'Verifier' => array (
  31.             'columns'           => array ( 'verified_by' ),
  32.             'refTableClass'     => 'Accounts',
  33.             'refColumns'        => array ( 'account_name' )
  34.         )
  35.     );
  36. }
  37.  
  38. class BugsProducts extends Zend_Db_Table_Abstract
  39. {
  40.     protected $_name = 'bugs_products';
  41.  
  42.     protected $_referenceMap    = array (
  43.         'Bug' => array (
  44.             'columns'           => array ( 'bug_id' ),
  45.             'refTableClass'     => 'Bugs',
  46.             'refColumns'        => array ( 'bug_id' )
  47.         ),
  48.         'Product' => array (
  49.             'columns'           => array ( 'product_id' ),
  50.             'refTableClass'     => 'Products',
  51.             'refColumns'        => array ( 'product_id' )
  52.         )
  53.     );
  54.  
  55. }

我们看到例子中定义了四个类:Accounts,Products,Bugs,BugsProducts。

其中Accounts,Products和Bugs是三个实体表,而BugsProducts是关系表。

我们再来分析一下这三个实体,一个Account有多个Bug,他们之间是一对多的关系,而Bug和Product是多对多的关系。

$_dependentTables是一个与该对象关联的对象名,这里注意,要写对象名而不是关联的数据库名。

$_referenceMap数组用来定义和其他表的关系,在这里可以设置和那些表有关系,有什么样的关系。

第一个设置的是Rule Key,也就是上面例子的'Reporter', 'Engineer'之类的。

Rule Key的作用其实就是一个关系的名字,并不需要和其他数据库表名或者其他对象名的名字一样。只是为了标记的,在后面的时候,我们可以看到这个Rule Key的作用。

每一个Rule下面都有如下的一些定义:(没有特殊说明,都以如上'Reporter'关系进行说明)

  • columns=> 设置和别的表关联的字段名,如上的'report_by'就是数据库中表Bugs的report_by字段。这里只有一个字段,也可以设置多个字段。
  • refTableClass=>用于设置与这个表发生关系的表。这里要注意,一定使用目标表的对象的名字而不是表名字,例子中就和'Account'对象发生了关联。
  • refColumns =>设置发生联系的表的字段。可以写多个,如果和多个字段发生联系的话,这里要和columns对应。这个设置其实是可选的,如果为空,关联字段自动被设置成为关联表的主键。上面例子中并没有使用主键作为关联字段,所以手动设置。
  • onDelete=>可选字段,设置当删除是的动作。
  • onUpdate=>可选字段,设置当更新表时的动作。

以上定义关系。


5.4.1从关联表中取数据:

如果我们已经得到了一个查询结果,我们可以通过一下语句去取得这个结果相关联的表的查询结果:

$row-> findDependentRowset ( $table, [ $rule ] );
这个方法一般使用与一多对应的两个实体表中,在多多对应的两个实体表和一个关系表如何从一个实体表取出另一个实体表的数据,我们会在下面叙述。

第一个字段 $table 是指和这个表想相联系的表对应的类名。第二个字段是可选的,是我们刚刚说到的 rule key ,就是这个关系的名字,如果省略,则默认为这个表中的第一个关系。下面是例子:
  1. $accountsTable = new Accounts ( );
  2. $accountsRowset = $accountsTable-> find ( 1234 );
  3. $user1234 = $accountsRowset-> current ( );
  4.  
  5. $bugsReportedByUser = $user1234-> findDependentRowset ( 'Bugs' );

例子中,我们先读取了一个编号为1234的用户,然后去查找这个家伙报了什么bug,由于zend默认是第一个关联,所以这里和Account发生关联的第一个就是'Reporter,所以就取出了Reporter的记录。

如果我们想取出其他的记录,比如Engineer,可以按照下面的办法:

  1. $accountsTable = new Accounts ( );
  2. $accountsRowset = $accountsTable-> find ( 1234 );
  3. $user1234 = $accountsRowset-> current ( );
  4.  
  5. $bugsAssignedToUser = $user1234-> findDependentRowset ( 'Bugs', 'Engineer' );

除了使用findDependentRowset之外,我们还可以使用叫做“魔术方法”(Magic Method)的机制。之所以这么叫,就是因为好像是在变魔术一样。

所以方法findDependentRowset('<TableClass>', '<Rule>')就可以等价于如下:
- $row->find<TableClass>()
- $row->find<TableClass>By<Rule>()

注:这个机制是我们最一开始是在Ruby on Rails里面看到的。这里的<TableClass>和<Rule>一定要使用和相关联的类名以及关联名(Rule Key)完全一样的名字,才可以生效。下面是例子:

  1. $accountsTable = new Accounts ( );
  2. $accountsRowset = $accountsTable-> find ( 1234 );
  3. $user1234 = $accountsRowset-> current ( );
  4.  
  5. // Use the default reference rule
  6. $bugsReportedBy = $user1234-> findBugs ( );
  7.  
  8. // Specify the reference rule
  9. $bugsAssignedTo = $user1234-> findBugsByEngineer ( );
5.4.2从父表取得字段

刚刚我们介绍了一多关系中的从一取多的方法,现在我们反过来,从多取一,其实是从多中的一个取他相对应的那个记录。类似的我们有这样的语句:
$row
-> findParentRow ( $table, [ $rule ] );
类似的,$table为类名,而可选参数$rule填入对应的Rule Key。下面是例子:
  1. $bugsTable = new Bugs ( );
  2. $bugsRowset = $bugsTable-> fetchAll ( array ( 'bug_status = ?' => 'NEW' ) );
  3. $bug1 = $bugsRowset-> current ( );
  4.  
  5. $reporter = $bug1-> findParentRow ( 'Accounts' );
和上面不太一样的是,上面返回的是一个多个记录的集合,而这次返回的必然是一条记录。下面的例子是设置Rule:
  1. $bugsTable = new Bugs ( );
  2. $bugsRowset = $bugsTable-> fetchAll ( array ( 'bug_status = ?', 'NEW' ) );
  3. $bug1 = $bugsRowset-> current ( );
  4.  
  5. $engineer = $bug1-> findParentRow ( 'Accounts', 'Engineer' );
只需要吧Rule填入就好了。相似的,这个方法也有“魔术字段”。 findParentRow('<TableClass>', '<Rule>')对应:
- $row->findParent<TableClass>()
- $row->findParent<TableClass>By<Rule>()


5.4.3取得多对多关系表的字段


上面两个方法讲述了一对多的使用,下面就是多对多了。我们使用如下方法取得多对多关系表的数据:
$row-> findManyToManyRowset ( $table, $intersectionTable, [ $rule2, [Zend_Db_Table_Select $select ]] );
这里参数变成了4个,因为需要增加一个关系表来存储多对多的关系。
$table是与之发生多对多关系的表的类名,$intersectionTable是中间存储关系的关系表的类名。
$rule1和$rule2是上面两个数据表的Rule Key。省略Rule Key的例子如下:
  1. $bugsTable = new Bugs ( );
  2. $bugsRowset = $bugsTable-> find ( 1234 );
  3. $bug1234 = $bugsRowset-> current ( );
  4.  
  5. $productsRowset = $bug1234-> findManyToManyRowset ( 'Products', 'BugsProducts' );
下面是该方法的全部参数调用例子:
  1. $bugsTable = new Bugs ( );
  2. $bugsRowset = $bugsTable-> find ( 1234 );
  3. $bug1234 = $bugsRowset-> current ( );
  4.  
  5. $productsRowset = $bug1234-> findManyToManyRowset ( 'Products', 'BugsProducts', 'Bug' );
这次的“魔术方法”是,对应 findManyToManyRowset('<TableClass>', '<IntersectionTableClass>', '<Rule1>', '<Rule2>')
- $row->find<TableClass>Via<IntersectionTableClass>()
- $row->find<TableClass>Via<IntersectionTableClass>By<Rule1>()
- $row->find<TableClass>Via<IntersectionTableClass>By<Rule1>And<Rule2>()
  1. $bugsTable = new Bugs ( );
  2. $bugsRowset = $bugsTable-> find ( 1234 );
  3. $bug1234 = $bugsRowset-> current ( );
  4.  
  5. // Use the default reference rule
  6. $products = $bug1234-> findProductsViaBugsProducts ( );
  7.  
  8. // Specify the reference rule
  9. $products = $bug1234-> findProductsViaBugsProductsByBug ( );

5.5、Zend_Db_Table_Definition

Zend_Db_Table_Definition 用于定义关联关系和对实例化Zend_Db_Table的相关选项配置的类。

5.5.1Basic Usage

所有继承实现Zend_Db_Table_Abstract 类的配置选项,都是可以使用定义描述文件的。通过在实例化时,将表的定义文件传递给类。
下面是表名和表对象之间的关联关系的定义。

注:如果“name”的定义被省略了,将采用表定义的key值(例如下面的“genre”部分)。
Example #1 Describing the Definition of a Database Data Model  数据库的数据模型定义描述
  1. $definition = new Zend_Db_Table_Definition (array (
  2.     'author' => array (
  3.         'name' => 'author',
  4.         'dependentTables' => array ( 'book' )
  5.         ),
  6.     'book' => array (
  7.         'name' => 'book',
  8.         'referenceMap' => array (
  9.             'author' => array (
  10.                 'columns' => 'author_id',
  11.                 'refTableClass' => 'author',
  12.                 'refColumns' => 'id'
  13.                 )
  14.             )
  15.         ),
  16.     'genre' => null,
  17.     'book_to_genre' => array (
  18.         'referenceMap' => array (
  19.             'book' => array (
  20.                 'columns' => 'book_id',
  21.                 'refTableClass' => 'book',
  22.                 'refColumns' => 'id'
  23.                 ),
  24.             'genre' => array (
  25.                 'columns' => 'genre_id',
  26.                 'refTableClass' => 'genre',
  27.                 'refColumns' => 'id'
  28.                 )
  29.             )
  30.         )
  31.     ) );
正如你看到的,继承实现Zend_Db_Table_Abstract类时相同的选项,也要在这个数组中定义。
当传入  Zend_Db_Table 构造函数时, 这个定义会被持久化到所有表中。它必须被创建目的是为了返回对应的行 。
下面是通过上面定义的主表实例化的例子,然后调用 findDependentRowset()和 findManyToManyRowset()方法:

Example #2 Interacting with the described definition 描述定义使用
  1. $authorTable = new Zend_Db_Table ( 'author', $definition );
  2. $authors = $authorTable-> fetchAll ( );
  3.  
  4. foreach ( $authors as $author ) {
  5.     echo $author-> id
  6.        . ': '
  7.        . $author-> first_name
  8.        . ' '
  9.        . $author-> last_name
  10.        . PHP_EOL;
  11.     $books = $author-> findDependentRowset ( 'book' );
  12.     foreach ( $books as $book ) {
  13.         echo '    Book: ' . $book-> title . PHP_EOL;
  14.         $genreOutputArray = array ( );
  15.         $genres = $book-> findManyToManyRowset ( 'genre', 'book_to_genre' );
  16.         foreach ( $genres as $genreRow ) {
  17.             $genreOutputArray [ ] = $genreRow-> name;
  18.         }
  19.         echo '        Genre: ' . implode ( ', ', $genreOutputArray ) . PHP_EOL;
  20.     }
  21. }

5.5.2Advanced Usage高级用法

有时可能会同时使用Zend_Db_Table和 Zend_Db_Table_Definition。要做到这一点,只需实现所有表的定义,即可。
允许采用Zend_Db_Table的具体类代替定义的KEY
基于上面的例子, 我们可以配置其中一个 实例化Zend_Db_Table_Abstract 的类,   而其它的表保持原有定义。

以下是具体的定义。

Example #3 Interacting A Mixed Use Zend_Db_Table Definition 混合使用Zend_Db_Table定义

  1. class MyBook extends Zend_Db_Table_Abstract
  2. {
  3.     protected $_name = 'book';
  4.     protected $_referenceMap = array (
  5.         'author' => array (
  6.             'columns' => 'author_id',
  7.             'refTableClass' => 'author',
  8.             'refColumns' => 'id'
  9.             )
  10.         );
  11. }
  12.  
  13. $definition = new Zend_Db_Table_Definition (array (
  14.     'author' => array (
  15.         'name' => 'author',
  16.         'dependentTables' => array ( 'MyBook' )
  17.         ),
  18.     'genre' => null,
  19.     'book_to_genre' => array (
  20.         'referenceMap' => array (
  21.             'book' => array (
  22.                 'columns' => 'book_id',
  23.                 'refTableClass' => 'MyBook',
  24.                 'refColumns' => 'id'
  25.                 ),
  26.             'genre' => array (
  27.                 'columns' => 'genre_id',
  28.                 'refTableClass' => 'genre',
  29.                 'refColumns' => 'id'
  30.                 )
  31.             )
  32.         )
  33.     ) );
  34.  
  35. $authorTable = new Zend_Db_Table ( 'author', $definition );
  36. $authors = $authorTable-> fetchAll ( );
  37.  
  38. foreach ( $authors as $author ) {
  39.     echo $author-> id
  40.        . ': '
  41.        . $author-> first_name
  42.        . ' '
  43.        . $author-> last_name
  44.        . PHP_EOL;
  45.     $books = $author-> findDependentRowset ( new MyBook ( ) );
  46.     foreach ( $books as $book ) {
  47.         echo '    Book: ' . $book-> title . PHP_EOL;
  48.         $genreOutputArray = array ( );
  49.         $genres = $book-> findManyToManyRowset ( 'genre', 'book_to_genre' );
  50.         foreach ( $genres as $genreRow ) {
  51.             $genreOutputArray [ ] = $genreRow-> name;
  52.         }
  53.         echo '        Genre: ' . implode ( ', ', $genreOutputArray ) . PHP_EOL;
  54.     }
  55. }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值