この記事の例では、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 の 4 つのクラスが定義されていることがわかります。このうち、Accounts、Products、および Bugs は 3 つのエンティティ テーブルであり、BugsProducts はリレーションシップ テーブルです。
これら 3 つのエンティティをもう一度分析してみましょう。アカウントには複数のバグがあり、それらの間には 1 対多の関係がありますが、バグと製品には多対多の関係があります。
$_dependentTables は、オブジェクトに関連付けられたオブジェクト名です。ここでは、関連付けられたデータベース名の代わりにオブジェクト名を記述する必要があります。
$_referenceMap 配列は、他のテーブルとの関係を定義するために使用され、それらのテーブルとの関係と、そこにどのような関係があるかを設定できます。最初に設定するのはルールキーで、上記の例では「Reporter」や「Engineer」などです。ルール キーの機能は実際にはリレーションシップの名前であり、他のデータベース テーブル名や他のオブジェクト名と同じである必要はありません。マーキングのためだけに、このルール キーの役割は後で確認できます。
各ルールには次の定義があります: (特別な指示はありません。すべては上記の「レポーター」関係で説明されています)
columns=> 他のテーブルに関連付けられたフィールド名を設定します。上記の 'report_by' は次のとおりです。テーブルの report_by フィールド データベース内のバグ。ここではフィールドは 1 つだけですが、複数のフィールドを設定することもできます。
refTableClass=> は、このテーブルに関連するテーブルを設定するために使用されます。この例では、テーブル名ではなく、ターゲット テーブル オブジェクトの名前を使用する必要があることに注意してください。
refColumns =>コンタクトが発生するテーブルのフィールドを設定します。複数のフィールドに関連する場合は、複数の列に対応する必要があります。この設定は実際にはオプションです。空の場合、関連フィールドは関連テーブルの主キーとして自動的に設定されます。上記の例では、主キーは関連フィールドとして使用されないため、手動で設定されます。
onDelete=> オプションのフィールドで、削除時のアクションを設定します。
onUpdate=> オプションのフィールドで、テーブルを更新するときのアクションを設定します。
上記は関係を定義します。
関連テーブルからデータを取得します:
すでにクエリ結果を取得している場合は、次のステートメントを通じてこの結果に関連付けられたテーブルのクエリ結果を取得できます:
$row->findDependentRowset($table, [$rule]);
このメソッドは通常、1 と 2 に対応する 2 を使用します。多くのエンティティ テーブルのうち、Duoduo の 2 つの対応するエンティティ テーブルと 1 つのリレーションシップ テーブル内の 1 つのエンティティ テーブルと別のエンティティ テーブルからデータを取得する方法について説明します。
最初のフィールド $table は、このテーブルが関連付けられているテーブルに対応するクラス名を参照します。 2 番目のフィールドはオプションであり、先ほど述べたルール キーであり、省略した場合は、テーブル内の最初のリレーションシップがデフォルトになります。以下は例です:
<?php $accountsTable = new Accounts(); $accountsRowset = $accountsTable->find(1234); $user1234 = $accountsRowset->current(); $bugsReportedByUser = $user1234->findDependentRowset('Bugs');
この例では、まず 1234 という番号のユーザーを読み取り、次にこの人が報告したバグを調べました。デフォルトでは zend が最初の関連付けであるため、これがアカウントに関連付けられた最初の関連付けになります。 1 つ目は「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();
親テーブルからフィールドを取得します:
先ほど、1 対多の関係で 1 から多への取得方法を紹介しました。今度は、逆に、多から 1 を取得します。 、対応する多数のレコードの 1 つから取得します。
同様に、次のようなステートメントがあります:
$row->findParentRow($table, [$rule]);
同様に、$table はクラス名で、オプションのパラメーター $rule には対応するルール キーが入力されます。以下は例です:
<?php $bugsTable = new Bugs(); $bugsRowset = $bugsTable->fetchAll(array('bug_status = ?' => 'NEW')); $bug1 = $bugsRowset->current(); $reporter = $bug1->findParentRow('Accounts');
上記と異なるのは、上記で返されるのは複数のレコードの集合であり、今回返されるのは 1 つのレコードである必要があることです。次の例はルールを設定する例です:
<?php $bugsTable = new Bugs(); $bugsRowset = $bugsTable->fetchAll('bug_status = ?', 'NEW'); $bug1 = $bugsRowset->current(); $engineer = $bug1->findParentRow('Accounts', 'Engineer');
ルールを入力するだけです。同様に、このメソッドにも「魔法のフィールド」があります。 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中文网!