本文實例講述了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('
- $row->find
- $row->find
註:這個機制是我們最一開始是在Ruby on Rails裡面看到的。這裡的
<?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('
- $row->findParent
- $row->findParent
範例:
取得多對多關係表的欄位:
上面两个方法讲述了一对多的使用,下面就是多对多了。我们使用如下方法取得多对多关系表的数据:
$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('
- $row->find
- $row->find
- $row->find
例子:
<?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程序设计有所帮助。
更多Zend Framework教程之Zend_Db_Table表关联实例详解相关文章请关注PHP中文网!