Zend Framework教程之Zend_Db_Table表关联实例详解


Posted in PHP onMarch 23, 2016

本文实例讲述了Zend Framework中Zend_Db_Table表关联用法。分享给大家供大家参考,具体如下:

介绍:

在RDBMS中,表之间有着各种关系,有一多对应,多多对应等等。

Zend框架提供了一些方法来方便我们实现这些关系。

定义关系:

下面是本文用的例子的关系定义:

<?php
class Accounts extends Zend_Db_Table_Abstract
{
  protected $_name      = 'accounts';
  protected $_dependentTables = array('Bugs');
}
class
class
  protected
  protected
class
  protected
}
Products extends Zend_Db_Table_Abstract
{
  protected $_name      = 'products';
  protected $_dependentTables = array('BugsProducts');
}
Bugs extends Zend_Db_Table_Abstract
{
  protected $_name      = 'bugs';$_dependentTables = array('BugsProducts');$_referenceMap  = array(
    'Reporter' => array(
      'columns'      => 'reported_by',
      'refTableClass'   => 'Accounts',
      'refColumns'    => 'account_name'
    ),
    'Engineer' => array(
      'columns'      => 'assigned_to',
      'refTableClass'   => 'Accounts',
      'refColumns'    => 'account_name'
    ),
    'Verifier' => array(
      'columns'      => array('verified_by'),
      'refTableClass'   => 'Accounts',
      'refColumns'    => array('account_name')
    )
  );
}
BugsProducts extends Zend_Db_Table_Abstract
{
  protected $_name = 'bugs_products';$_referenceMap  = array(
    'Bug' => array(
      'columns'      => array('bug_id'),
      'refTableClass'   => 'Bugs',
      'refColumns'    => array('bug_id')
    ),
    'Product' => array(
      'columns'      => array('product_id'),
      'refTableClass'   => 'Products',
      'refColumns'    => array('product_id')
    )
  );

我们看到例子中定义了四个类: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=>可选字段,设置当更新表时的动作。

以上定义关系。

从关联表中取数据:

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

$row->findDependentRowset($table, [$rule]);

这个方法一般使用与一多对应的两个实体表中,在多多对应的两个实体表和一个关系表如何从一个实体表取出另一个实体表的数据,我们会在下面叙述。

第一个字段$table是指和这个表想相联系的表对应的类名。第二个字段是可选的,是我们刚刚说到的rule key,就是这个关系的名字,如果省略,则默认为这个表中的第一个关系。下面是例子:

<?php
$accountsTable   = new Accounts();
$accountsRowset   = $accountsTable->find(1234);
$user1234      = $accountsRowset->current();
$bugsReportedByUser = $user1234->findDependentRowset('Bugs');

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

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

<?php
$accountsTable   = new Accounts();
$accountsRowset   = $accountsTable->find(1234);
$user1234      = $accountsRowset->current();
$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)完全一样的名字,才可以生效。下面是例子:

<?php
$accountsTable  = new Accounts();
$accountsRowset  = $accountsTable->find(1234);
$user1234     = $accountsRowset->current();
// Use the default reference rule
$bugsReportedBy  = $user1234->findBugs();// Specify the reference rule
$bugsAssignedTo  = $user1234->findBugsByEngineer();
<?php
$bugsTable     = new Bugs();
$bugsRowset    = $bugsTable->fetchAll('bug_status = ?', 'NEW');
$bug1       = $bugsRowset->current();
// Use the default reference rule
$reporter     = $bug1->findParentAccounts();// Specify the reference rule
$engineer     = $bug1->findParentAccountsByEngineer();

从父表取得字段:

刚刚我们介绍了一多关系中的从一去多的方法,现在我们反过来,从多取一,其实是从多中的一个取他相对应的那个记录。

类似的我们有这样的语句:

$row->findParentRow($table, [$rule]);

类似的,$table为类名,而可选参数$rule填入对应的Rule Key。下面是例子:

<?php
$bugsTable     = new Bugs();
$bugsRowset    = $bugsTable->fetchAll(array('bug_status = ?' => 'NEW'));
$bug1       = $bugsRowset->current();
$reporter     = $bug1->findParentRow('Accounts');

和上面不太一样的是,上面返回的是一个多个记录的集合,而这次返回的必然是一条记录。下面的例子是设置Rule:

<?php
$bugsTable     = new Bugs();
$bugsRowset    = $bugsTable->fetchAll('bug_status = ?', 'NEW');
$bug1       = $bugsRowset->current();
$engineer     = $bug1->findParentRow('Accounts', 'Engineer');

只需要吧Rule填入就好了。相似的,这个方法也有“魔术字段”。findParentRow('<TableClass>', '<Rule>')对应:

- $row->findParent<TableClass>()
- $row->findParent<TableClass>By<Rule>()

例子:

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

上面两个方法讲述了一对多的使用,下面就是多对多了。我们使用如下方法取得多对多关系表的数据:

$row->findManyToManyRowset($table, $intersectionTable, [$rule1, [$rule2]]);

这里参数变成了4个,因为需要增加一个关系表来存储多对多的关系。

$table是与之发生多对多关系的表的类名,$intersectionTable是中间存储关系的关系表的类名。$rule1和$rule2是上面两个数据表的Rule Key。省略Rule Key的例子如下:

<?php
$bugsTable    = new Bugs();
$bugsRowset    = $bugsTable->find(1234);
$bug1234     = $bugsRowset->current();
$productsRowset  = $bug1234->findManyToManyRowset('Products', 'BugsProducts');

下面是该方法的全部参数调用例子:

<?php
$bugsTable    = new Bugs();
$bugsRowset    = $bugsTable->find(1234);
$bug1234     = $bugsRowset->current();
$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>()

例子:

<?php
$bugsTable    = new Bugs();
$bugsRowset    = $bugsTable->find(1234);
$bug1234     = $bugsRowset->current();
// Use the default reference rule
$products     = $bug1234->findProductsViaBugsProducts();// Specify the reference rule
$products     = $bug1234->findProductsViaBugsProductsByBug();

希望本文所述对大家基于Zend Framework框架的PHP程序设计有所帮助。

PHP 相关文章推荐
require(),include(),require_once()和include_once()区别
Mar 27 PHP
php join函数应用
May 04 PHP
php学习笔记 数组遍历实现代码
Jun 09 PHP
编写安全 PHP应用程序的七个习惯深入分析
Jun 08 PHP
PHP中Session引起的脚本阻塞问题解决办法
Apr 08 PHP
php简单smarty入门程序实例
Jun 11 PHP
php结合ACCESS的跨库查询功能
Jun 12 PHP
visual studio code 调试php方法(图文详解)
Sep 15 PHP
PHP实现转盘抽奖算法分享
Apr 15 PHP
PHP实现的CURL非阻塞调用类
Jul 26 PHP
深入研究PHP中的preg_replace和代码执行
Aug 15 PHP
phpinfo无法显示的原因及解决办法
Feb 15 PHP
SSO单点登录的PHP实现方法(Laravel框架)
Mar 23 #PHP
Zend Framework开发入门经典教程
Mar 23 #PHP
php resizeimage 部分jpg文件 生成缩略图失败的原因分析及解决办法
Mar 23 #PHP
Zend Framework教程之Zend_Config_Ini用法分析
Mar 23 #PHP
PHP正则获取页面所有图片地址
Mar 23 #PHP
Zend Framework教程之Zend_Config_Xml用法分析
Mar 23 #PHP
php获取文件后缀的9种方法
Mar 22 #PHP
You might like
php 删除无限级目录与文件代码共享
2008/11/22 PHP
PHP 高级课程笔记 面向对象
2009/06/21 PHP
Windows下安装PHP单元测试环境PHPUnit图文教程
2014/10/24 PHP
PHP之正则表达式捕获组与非捕获组(详解)
2015/07/29 PHP
php自定义函数实现汉字转换utf8编码的方法
2016/09/29 PHP
实例讲解通过​PHP创建数据库
2019/01/20 PHP
PHP基础之输出缓冲区基本概念、原理分析
2019/06/19 PHP
PHP生成随机密码4种方法及性能对比
2020/12/11 PHP
用js+xml自动生成表格的东西
2006/12/21 Javascript
用Javascript读取中文COOKIE的解决办法
2007/02/15 Javascript
用ASP将SQL搜索出来的内容导出为TXT的代码
2007/07/27 Javascript
javascript onkeydown,onkeyup,onkeypress,onclick,ondblclick
2009/02/04 Javascript
JS的replace方法详细介绍
2012/11/09 Javascript
js中复制行和删除行的操作实例
2013/06/25 Javascript
编写简单的jQuery提示插件
2014/12/21 Javascript
jQuery中$.ajax()和$.getJson()同步处理详解
2015/08/12 Javascript
react中fetch之cors跨域请求的实现方法
2018/03/14 Javascript
webpack4 升级迁移的实现
2018/09/12 Javascript
在vue中使用echarts图表实例代码详解
2018/10/22 Javascript
开源一个微信小程序仪表盘组件过程解析
2019/07/30 Javascript
五分钟搞懂Vuex实用知识(小结)
2019/08/12 Javascript
Python批量转换文件编码格式
2015/05/17 Python
Python编程中对super函数的正确理解和用法解析
2016/07/02 Python
python绘制立方体的方法
2018/07/02 Python
python求numpy中array按列非零元素的平均值案例
2020/06/08 Python
Python 字符串池化的前提
2020/07/03 Python
加拿大拼图大师:Puzzle Master
2020/12/28 全球购物
中专自我鉴定范文
2013/10/16 职场文书
物业管理应届生求职信
2013/10/28 职场文书
师范教师大学生职业生涯规划范文
2014/01/05 职场文书
护理专业毕业生自荐信范文
2014/01/05 职场文书
党支部书记先进事迹
2014/01/17 职场文书
金融管理毕业生求职信
2014/03/03 职场文书
离婚协议书格式
2014/11/21 职场文书
农村婚礼司仪主持词
2015/06/29 职场文书
2016年中学植树节活动总结
2016/03/16 职场文书