DB_Table_Database は、 リレーショナルデータベース用のデータベース抽象化クラスです。 DB_Table クラスの最上位に位置する層となります。 DB_Table_Database オブジェクトの各テーブルは DB_Table オブジェクトで表します。 DB_Table_Database オブジェクトと DB_Table オブジェクト群との最大の違いは、 DB_Table_Database オブジェクトのプロパティにはデータベース全体を表すモデルが含まれているという点です。 ここにはテーブル間のリレーションといった情報も含まれます。
DB_Table_Database の機能は次のとおりです。
オブジェクト指向の記法による リレーショナルデータベース内のリレーションの表現。 これには、多対多の関連を作成する関連テーブルも含まれます。
INSERT、UPDATE、DELETE および SELECT コマンド用のシンプルな API。 DB_Table クラスの API とよく似ています。
任意の数のテーブルの内部結合における結合条件の自動作成。 これは、テーブル名やカラム名にもとづいて行います。
追加や更新の際に、オプションで行う PHP での外部キー整合性チェック。
SQL の ON DELETE トリガーや ON UPDATE トリガーによる連鎖更新の、PHP によるエミュレート。
PHP による、データベーススキーマ全体の文字列へのシリアライズとその復元。
MDB2 XML スキーマの使用による XML へのシリアライズとその復元 (XML からの復元には PHP 5 が必要です)。
配下の DB_Table オブジェクトすべてに共通の値を設定するためのさまざまなメソッド。
SQL クエリの作成を支援するさまざまなユーティリティメソッド。
DB_Table と同様、DB_Table_Database は DB あるいは MDB2 のデータベース接続オブジェクトを使用します。 このクラスは PHP 4 と PHP 5 の両方で使用できますが、一部例外があります。 fromXML() メソッドは XML データベーススキーマから DB_Table_Database オブジェクトを作成するものですが、 このメソッドは PHP 5 でしか動きません。
DB_Table_Database クラスは、抽象基底クラス DB_Table_Base を継承したものです。 DB_Table_Base から継承したメソッドやプロパティについては、 このページの目次で "(DB_Table_Base から継承)" のように示します。
このチュートリアルでは、サンプルを使用して DB_Table_Database クラスでリレーショナルデータベースとのインターフェイスを作成する方法を説明します。
目次
addTable() - テーブルの追加
addRef() - 参照の追加
addLink() - リンクテーブルの宣言
select()、selectResult() および selectCount() (DB_Table_Base から継承)
buildFilter() (DB_Table_Base から継承)
buildSQL() (DB_Table_Base から継承)
このチュートリアルでは、TestDB という名前のサンプルデータベースを用いて DB_Table_Database オブジェクトを利用します。 このサンプルデータベースについては後述します。RDBMS のテーブルに対応する DB_Table オブジェクトのインスタンスをまず最初に作成し、 それを親となる DB_Table_Database オブジェクトに追加 (リンク) します。
サンプルデータベース TestDB には、 さまざまな人たちの名前と電話番号、そして住所を格納することにします。 このデータベースは 4 つのテーブルで構成されています。 人の名前、電話番号、そして住所は、それぞれ Person、Phone、Addres という名前のテーブルに格納します。 複数の人がひとつの電話番号を共有することもありえますし、 逆に一人で複数の電話番号を保持することもありえます。 そのため、このデータベースでは Person と Phone の間に多対多のリレーションシップを作成できるようにします。 このリレーションシップを確率するために、PersonPhone という名前のリンクテーブルを追加します。 このテーブルでは、Person と Phone の外部キー参照を保持します。
DB_Table オブジェクトのインスタンスを作成してからでないと、 親の DB_Table_Database インスタンスにそれを追加することはできません。 DB_Table オブジェクトを作成する一般的な方法 (このクラスのチュートリアルで説明しています) は、各テーブルに対して DB_Table のサブクラスを個別に作成し、 そのサブクラスのインスタンスを作成するというものです。 このチュートリアルでは、たとえば "Entity" という名前のテーブルに対して関連づける DB_Table のサブクラスのクラス名は Entity_Table とし、 そのインスタンス名を $Entity とすることにします。 この方式は、DB_Table_Generator が生成するコードが用いている規約と同じです。
以下のコードは、Person テーブルに対応する Person_Table のサブクラスを定義するものです。
<?php require_once 'DB/Table.php' class Person_Table extends DB_Table { // カラムを定義します $col = array ( 'PersonID' => array('type' => 'integer', 'require' => true), 'FirstName' => array('type' => 'char', 'size' => 32, 'require' => true), 'MiddleName' => array('type' => 'char', 'size' => 32), 'LastName' => array('type' => 'char', 'size' => 64, 'require' => true), 'NameSuffix' => array('type' => 'char', 'size' => 16), 'AddressID' => array('type' => 'integer') ); // インデックスを定義します。PersonID は主キーとして宣言します $idx = array( 'PersonID' => array('cols' => 'PersonID', 'type' => 'primary'), 'AddressID' => array('cols' => 'AddressID', 'type' => 'normal') ); // 'PersonID' を自動インクリメント型のカラムとして宣言します $auto_inc_col = 'PersonID'; } ?> |
$auto_inc_col プロパティに代入している部分に注目しましょう。これは、 最近 DB_Table に追加されたプロパティです。 $auto_inc_col には、'自動インクリメント' として宣言するカラムの名前を設定します。 このカラムについての自動インクリメント機能は、 DB_Table の insert メソッドで DB あるいは MDB2 のシーケンスを用いて実装されます。
次のコードは、TestDB データベースの残りのテーブル Phone、Address および PersonPhone に対応する DB_Table のサブクラスを先ほどと同じ方法で定義するものです。
<?php class Address_Table extends DB_Table { $col = array( 'AddressID' => array('type' => 'integer', 'require' => true), 'Building' => array('type' => 'char', 'size' =>16), 'Street' => array('type' => 'char', 'size' => 64), 'UnitType' => array('type' => 'char', 'size' => 16), 'Unit' => array('type' => 'char', 'size' => 16), 'City' => array('type' => 'char', 'size' => 64), 'StateAbb' => array('type' => 'char', 'size' => 2), 'ZipCode' => array('type' => 'char', 'size' => 16) ); $idx = array( 'AddressID' => array('cols' => 'AddressID', 'type' => 'primary'), ); $auto_inc_col = 'AddressID'; } ?> |
<?php class Phone_Table extends DB_Table { $col = array( 'PhoneID' => array('type' => 'integer', 'require' => true), 'PhoneNumber' => array('type' => 'char', 'size' => 16, 'require' => true), 'PhoneType' => array('type' => 'char', 'size' => 4) ); $idx = array( 'PhoneID' => array('cols' => 'PhoneID', 'type' => 'primary') ); $auto_inc_col = 'PhoneID'; } ?> |
<?php class PersonPhone_Table extends DB_Table { $col = array( 'PersonID' => array('type' => 'integer', 'require' => true), 'PhoneID' => array('type' => 'integer', 'require' => true) ); $idx = array( 'PersonID' => array('cols' => 'PersonID', 'type' => 'normal'), 'PhoneID' => array('cols' => 'PhoneID', 'type' => 'normal') ); } ?> |
次のコードは、各テーブルに関連づけた DB_Table のサブクラスのインスタンスを作成するものです。
<?php $Person = new Person_Table($conn, 'Person', 'safe'); $Address = new Address_Table($conn, 'Address', 'safe'); $Phone = new Phone_Table($conn, 'Phone', 'safe'); $PersonPhone = new PersonPhone_Table($conn, 'PersonPhone', 'safe'); ?> |
コンストラクタ文は、DB_Table サブクラスの定義とは別のファイルに記述することをお勧めします。 そうすれば、 DB_Table や DB_Table_Database のオブジェクトを シリアライズや復元 するのが簡単になります。 DB_Table サブクラスのインスタンスを復元する php ファイルはそのサブクラスの定義にアクセスできる必要があるが、 コンストラクタ文はそこに含まれてはならないからです。 各 DB_Table サブクラスの定義を別々のファイルに記述し、 そのファイル名はサブクラス名に拡張子 .php をつけたものにしておきます。 こうすることで、オブジェクトをシリアライズする際にサブクラスの定義が自動的に読み込まれます。 これについては 後ほど 説明します。
DB_Table オブジェクトを作成するもうひとつの方法としては、 DB_Table のサブクラスではなく DB_Table 自身のインスタンスを作成するという方法があります。 この場合、最初に DB_Table のオブジェクトを作成した時点ではテーブルのスキーマについての情報が含まれていません。 パブリックプロパティ $col および $idx を設定してテーブルのスキーマを定義する必要があります。 以下のコード例は、Person テーブルに対応する DB_Table のインスタンスを作成するものです。
<?php $Person = new DB_Table($conn, 'Person'); $Person->col['PersonID'] = array('type' => 'integer', 'require' => true); $Person->col['FirstName'] = array('type' => 'char', 'size' => 32, 'require' => true); $Person->col['MiddleName'] = array('type' => 'char', 'size' => 32); $Person->col['LastName'] = array('type' => 'char', 'size' => 64, 'require' => true); $Person->col['NameSuffix'] = array('type' => 'char', 'size' => 16); $Person->col['AddressID'] = array('type' => 'integer'); $Person->idx['PersonID'] = array('cols' => 'PersonID', 'type' => 'primary'); $Person->idx['PersonID'] = array('cols' => 'PersonID', 'type' => 'normal'); $Person->auto_inc_col = 'PersonID'; ?> |
DB_Table_Database オブジェクトのインスタンスは、 まず空の状態で作成します。そこに、テーブルや外部キー参照、リンク等を追加していきます。 コンストラクタのインターフェイスは、このようになります。
void DB_Table_Database(DB/MDB2 object $conn, string $name) |
<?php require_once 'DB/Table/Database.php' $conn = DB::connect("mysqli://$user:$password@$host"); $db = new DB_Table_Database($conn, 'TestDB'); ?> |
DB_Table オブジェクトと DB_Table_Database オブジェクトのインスタンスを作成した後でリレーショナルデータベースのモデルを作成するには、 まずデータベースオブジェクトにテーブルオブジェクトを追加し、 次に外部キー参照の宣言を行い、 それから多対多の関係を表すリンクテーブルの宣言を行う必要があります。
DB_Table オブジェクトのインスタンスを作成したら、 DB_Table_Database::addTable() メソッドで それを親データベースに追加することができます。 このメソッドのインターフェイスは次のようになります。
true|PEAR_Error addTable(object &$Table) |
次のコードは、サンプルデータベースの 4 つのテーブルを DB_Table_Database オブジェクト $db に追加します。
<?php $db->addTable($Person); $db->addTable($Address); $db->addTable($Phone); $db->addTable($PersonPhone); ?> |
テーブルをデータベースに追加したあとで、 複数テーブル間の参照を追加するには addRef() メソッドを使用します。
構文 (単純版):
true|PEAR_Error addRef(string $ftable, string|array $fkey, string $rtable, [string|array $rkey] ) |
<?php $db->addRef('Person', 'AddressID', 'Address', 'AddressID'); ?> |
<?php $db->addRef('Person', 'AddressID', 'Address'); ?> |
2 つのテーブル間の参照を追加できるのは、参照元と参照先の DB_Table オブジェクトを両方作成して DB_Table_Datbase のインスタンスに追加した後のことです。
あるテーブルを、他のふたつのテーブルの多対多の関係を確立するための "リンク" テーブルとして宣言することができます。 この宣言をすると、autoJoin メソッドの挙動が変化します。 $link という名前のテーブルをリンクテーブルとして宣言し、 $table1 と $table2 の間の多対多のリレーションを表すものとした場合、 autoJoin メソッドが $table1 と $table2 を連結する際に必要に応じてこのテーブルを使用します。
addLink() メソッドには、 リンクテーブル (関連テーブル) として使用するテーブルと 関連づける 2 つのテーブルを指定します。
構文:
true|PEAR_Error addLink(string $table1, string $table2, string $link) |
たとえば、
<?php $db->addLink('Person', 'Phone, 'PersonPhone') ?> |
addLink() メソッドで、 ふたつのテーブルの間に複数のリンクテーブルを宣言することもできます。 しかし、そんなことをするとリンクの宣言が無意味になってしまいます。 autoJoin() メソッドが複数のテーブルを連結する際にリンクテーブルを使用することになったとき、 複数のリンクテーブルが指定されているとこのメソッドが失敗してしまうからです。
以下のコマンド
<?php $db->addAllLinks() ?> |
すべてのテーブルが追加され、すべての参照が追加され、 そしてすべてのリンクが追加された時点でデータベースモデルが完成したことになります。
サンプル用にディレクトリを作成し、 データベースへのインターフェイス用のコードをすべてそこにまとめていくようにします。 DB_Table の各サブクラスの定義を個別のファイルに分割し、 クラス名の後ろに拡張子 '.php' をつけた名前のファイルでそのディレクトリに保存します。 さらに、'Database.php' という名前のファイルをひとつ作成します。 このファイルで DB あるいは MDB2 の接続を作成し、 各テーブル用のオブジェクトを作成し、そして親の DB_Table_Database オブジェクトを作成します。 この構造は、既存のデータベースをもとに DB_Table_Generator が自動生成するコードと同じものです。 サンプルデータベース用の最小限の 'Database.php' ファイルを以下に示します。
例 39-1Database.php ファイル
|
このサンプルファイルは、既存のデータベースをもとに DB_Table_Generator が作成する雛形ファイルとよく似ています。 主な違いは、自動生成されたファイルにはいくつかコメントされていたり編集を要したりする場所 (たとえばデータベースの DSN 定義部分など) があるということです。この例では、 addAllLinks() をコールすると 'PersonPhoneAssoc' が 'Person' と 'Phone' を連結することを正しく認識します。 このサンプルには、'ON DELETE' や 'ON UPDATE' といったトリガーの定義はありません。これは後で説明しますが、 同じファイルの最後に追加することができます。
deleteTable()、 deleteRef() および deleteLinks() メソッドを使用すると、それぞれテーブルや外部キー参照、 リンクテーブルの宣言を DB_Table_Database モデルから削除することができます。
deleteTable() - データベースモデルからテーブルを削除する
構文:
void deleteTable(string $table) |
deleteRef() - データベースモデルから参照を削除する
構文:
void deleteRef(string $ftable, string $rtable) |
deleteLink() - リンクテーブルの宣言を削除する
構文:
void deleteLink(string $table1, string $table2, [string $link]) |
DB_Table_Database は、参照整合性を保つためのアクションをオプションで提供しています。 これは ANSI SQL で定義されているものですが、これをサポートしていないデータベースもあります (たとえば SQLite やデフォルトの MySQL エンジンなど)。 DB_Table_Database は、オプションで ON DELETE や ON UPDATE アクション (たとえば連鎖削除など) の PHP によるエミュレート機能を提供しています (ここで説明します)。 また、同じくオプションで、追加や更新の前に外部キーの値の検証を行います (あとで 説明します)。
参照に関連づけられた ON DELETE および ON UPDATE アクションがもしあった場合にそれを宣言するには、 addRef() の追加のパラメータを使用するか、あるいは setOnDelete() および setOnUpdate() を使用します。
参照される行が削除されたり更新されたりしたときのアクションを宣言するには、 モデルに参照を追加する際の addRef() メソッドに 2 つのオプションパラメータを指定します。 次の例は addRef() の拡張形式で、 上で示した PersonPhone から Person への参照を追加するものです。 また、Person の行が削除されたときの cascade アクションと更新されたときの restrict アクションを宣言しています。
<?php $db->addRef('PersonPhone', 'PersonID', 'Person', null, 'cascade', 'restrict'); ?> |
上の例で 5 番目のパラメータに指定した値 'cascade' の意味は、 Person の行が削除されたときに、対応する PersonPhone の行をすべて削除する (連鎖削除) ということです。 6 番目のパラメータに指定した 'restrict' は、PersonPhone の行から参照されている Person テーブルの主キー PersonID を更新しようとしたときにそれを阻止します (update アクションを '制限' します)。そして update メソッドはエラーを発生させます。
addRef() メソッドの完全なインターフェイスは次のようになります。
true|PEAR_Error addRef(string $ftable, mixed $fkey, string $rtable, [mixed $rkey], [string|null $on_delete], [string|null $on_update]) |
'cascade' | 'restrict' | 'set null' | 'set default' |
次の例は、サンプルデータベースに必要なすべての外部キー参照と同時に、 適切なトリガーアクションを宣言するものです。
<?php $db->addRef('Person', 'AddressID', 'Address', null, 'set null', 'cascade'); $db->addRef('PersonPhone', 'PersonID', 'Person', null, 'cascade', 'cascade'); $db->addRef('PersonPhone', 'PhoneID', 'Phone', null, 'cascade', 'cascade'); ?> |
外部キー参照でのトリガーアクションを変更したり無効にしたりするために、 setOnDelete() メソッドや setOnUpdate() メソッドを使用することもできます。
構文:
void setOnDelete(string $ftable, string $rtable, string|null $action) void setOnUpdate(string $ftable, string $rtable, string|null $action) |
たとえば次のコードは、'PersonPhone' から 'Person' への参照の 'on_update' アクションを 'restrict' に変更します。
<?php $db->setOnUpdate('PersonPhone', 'Person', 'restrict'); ?> |
参照トリガーアクションの PHP でのエミュレートをデータベース全体で有効あるいは無効にするには setActOnDelete() および setActOnUpdate() メソッドを使用します。
構文:
void setActOnDelete(bool $flag) void setActOnUpdate(bool $flag) |
デフォルトでは、DB_Table_Database で外部キーを持つテーブルに行を追加したり変更したりする前には外部キーの値の妥当性を検証します。 つまり、行を追加したり外部キーカラムの値を変更したりする前に、 DB_Table_Database の insert() メソッドや update() メソッドは参照先テーブルの既存の行の値を確認するクエリを実行するのです。 デフォルトでは、チェックに失敗した場合にこれらのメソッドはエラーを返し、 データの変更は行いません。
PHP レベルでの外部キーの妥当性チェックをデータベース内のすべてのテーブルで有効あるいは無効にするには setCheckFKey() メソッドを使用します。 このメソッドのインターフェイスは次のとおりです。
void setCheckFKey(bool $flag) |
DB_Table_Database は、SQL の select 文用のオブジェクト指向のインターフェイスを提供します。 これは DB_Table が提供するものとほぼ同じです。
DB_Table と同様、 DB_Table_Database ではクエリを配列で表します。 配列の各要素が SQL の select 文における句を表します。 たとえば、AnyTown の Oak Street に住むすべての人の名前をサンプルデータベースから取得するクエリは、 次のようになります。
<?php $oak = array( 'select' => 'Person.FirstName, Person.LastName, Address.Building', 'from' => 'Person, Address', 'where' => "Person.AddressID = Address.AddressID\n" . " AND Address.Street = 'Oak Street'\n" . " AND Address.City = 'AnyTown'", 'order' => 'Address.Building' ); ?> |
<?php echo $db->buildSQL($oak); ?> |
SELECT Person.FirstName, Person.LastName, Address.Building FROM Person, Address WHERE Person.AddressID = Address.AddressID AND Address.Street = 'Oak Street' AND Address.City = 'AnyTown' ORDER BY Address.Building |
DB_Table と同様、 クエリ配列を public プロパティ配列 $sql に格納することもできます。
<?php $db->sql['oak'] = $oak ?> |
select*() メソッドは、 DB_Table_Database クラスも DB_Table クラスも DB_Table_Base クラスから継承しており、 そのインターフェイスや振る舞いは同じです。 また、これら 3 つのメソッドのインターフェイスもすべて同じです。 最初の引数は必須で、先ほど保存したクエリ配列のキー
<?php $result = $db->select('oak') ?> |
<?php $result = $db->select($oak) ?> |
これら 3 つの select* メソッド select()、 selectCount() そして selectResult() に共通のインターフェイスは、このようになります。
mixed select*( array|string $sql_key, [string $filter], [string $order], [int $start], [int $count], [array $params]) |
autoJoin() - カラム名の配列やテーブル名の配列をパラメータとして受け取り、 それらを自動的に join した WHERE 句を含むクエリ配列を返します。
構文:
array|PEAR_Error autoJoin([array $cols], [array $tables], [string $filter]) |
次の例は、ある人の名前と自宅の電話番号そして住所を取得するクエリを作成して実行するものです。 必要なカラムを指定して作成しています。 今回のサンプルデータベースの場合、これは 4 つのテーブルすべてを連結することになります。
<?php $cols = array('FirstName', 'LastName', 'PhoneNumber', 'Building', 'Street', 'City') $report = $db->autoJoin($cols, "Phone.PhoneType = 'HOME'"); $result = $db->select($report); ?> |
このクエリ配列に対応する SQL コマンドを取得するには buildSQL() を使用します。 この例の場合、
<?php echo $db->buildSQL($report); ?> |
SELECT Person.FirstName, Person.LastName, Phone.PhoneNumber, Address.Building, Address.Street, Address.City FROM Person, Phone, Address, PersonPhone WHERE PersonPhone.PhoneID = Phone.PhoneID AND PersonPhone.PersonID = Person.PersonID AND Person.AddressID = Address.AddressID |
次の例では $cols パラメータが null となっています。 しかし、そのかわりに連結するテーブル名を $tables パラメータで指定しています。
<?php $tables = array('Person', 'Address', 'Phone'); $report = $db->autoJoin(null,$tables); $result = $db->select($report); ?> |
SELECT * FROM Person, Phone, Address, PersonPhone WHERE PersonPhone.PhoneID = Phone.PhoneID AND PersonPhone.PersonID = Person.PersonID AND Person.AddressID = Address.AddressID |
アルゴリズム: autoJoin() は適切な結合条件が存在するかどうかを探し、 曖昧さがない状態で見つかった場合にはそれを使用します。 参照構造やリンクテーブルによって複数の結合が可能な場合や 適切な結合条件が作成できない場合には PEAR Error を返します。 このメソッドはまず最初に $col プロパティおよび $table プロパティを調べ、連結しなければならないテーブルの一覧を取得します。 それから、連結されたテーブルのネットワーク (joined set) を作成します。まずひとつのテーブルから始め、そこにまだ連結されていないテーブル (the unjoined set) の内容を順に追加していくという方式です。 この処理は、まず最初に joined set の核として使用するテーブルをひとつ取り出し、 unjoined set の中からそのテーブルに連結できるテーブルを探していきます。 これ以降の処理も同様に、unjoined set の中のテーブルを順に調べて joined set のいずれかのテーブルに連結できるもの (joined set の中のテーブルを参照している、あるいは参照されているもの) を探すというようになります。 まだ連結されていないテーブルの中で joined set 内のひとつのテーブルだけに連結できるテーブルが見つかった場合はそのテーブルを joined set に追加し、次のテーブルを探し始めます。unjoined set の中に joined set の複数のテーブルに連結できるテーブルが見つかった場合は、 結合条件が曖昧であるというエラーを返します。このメソッドはツリーグラフ (テーブルがノードに対応する) 状の結合にのみ対応しており、 複数接続された連結には対応していません。 unjoined set のテーブルの中に、joined set 内のテーブルに直接連結できるものが見つからない場合は、 unjoined set 内をもう一度見直し、リンクテーブル経由で joined set 内のひとつのテーブルに連結できるテーブルを探します。 リンクテーブルを使用して joined set 内の複数のテーブルに連結できるテーブルが見つかった場合は、 エラーとなります。まだ連結されていないテーブルの中に、 直接であってもリンクテーブル経由であっても連結できないものが見つかった場合は、 テーブルのセットが連結できないというエラーとなります。
quote メソッドは、パラメータ $value を SQL リテラル文字列で表したものを返します。
構文:
string quote(mixed $value) |
buildFilter() は SQL の論理式を返します。 この式は、指定したデータベースのカラムが SQL のリテラル値に等しい場合に true となります。パラメータには配列を渡す必要があります。 配列のキーがカラム名、そして配列の値が要求する内容となります。
次の例は、buildFilter メソッドを使用して Peoria の Pine St. に住む人を抽出するフィルタを作成するものです。
<?php $data = array('Street' => 'Pine St', 'City' => 'Peoria'); $filter = $db->buildFilter($data); ?> |
Street = 'Pine St' AND City = 'Peoria' |
buildSQL() - select* メソッドで使用する形式のクエリ配列を受け取り、 対応する SQL コマンド文字列を返します。これは select*() メソッドから内部的にコールされます。buildSQL() と select*() メソッドは、どちらも DB_Table_Base から継承したものです。
構文: インターフェイスは select*() メソッドに似ています
string|PEAR_Error buildSQL(array|string $query, [string $filter], [string $order], [int $start], [int $count]) |
validCol() - カラム名を検証し、 (必要に応じて) 曖昧さを解決します。
構文:
array|PEAR_Error validCol(string $col, [array $from]) |
$col パラメータは、カラム名の前にテーブル名をつけて SQL で使用する table.column 形式とすることもできますし、 もしカラム名が曖昧さなしに解決できるのであればテーブル名をつけなくてもかまいません。 validCol の返り値は、成功した場合は配列となります。 配列の 2 番目の要素は修飾していないカラム名で、最初の要素はテーブル名 ($col がテーブル名で修飾されているか、 あるいはテーブル名が一意に決まる場合) あるいはカラム名の配列 ($col がテーブル名で修飾されておらず、 そのカラム名が複数のテーブルに存在する場合) となります。指定した名前のカラムがデータベースに存在しない場合は PEAR error が返されます。
オプションの $from パラメータは、$col が明示的にテーブル名で修飾されていない場合にのみ使用します。 $from はテーブル名 (SQL の select 文の from 句で指定したもの) の配列で、ここから指定した名前のカラムを探します。 この場合、validCol は最初に $from のテーブルを探し、 一意な結果が得られた場合にテーブル名を返します。 指定した名前のカラムを含むテーブルが $from の中に複数見つかった場合は、返り値はそのセットとなります。 $from の中に指定した名前のカラムを含むテーブルがなかった場合は、 検索範囲をデータベース内のすべてのテーブルに広げます。 それでもまだ複数の選択肢が残った場合 (from の複数のテーブルがあてはまった場合、 あるいはデータベース内のそれ以外のテーブルの中に複数あてはまるものがあった場合)、 もしそのカラムがテーブルの外部キーではないテーブルがあるのなら、 カラムが外部キーとなっているテーブルを除外します。
DB_Table_Database の insert()、delete() および update() メソッドのインターフェイスや振る舞いは、 DB_Table の対応するメソッドと似ています。 唯一のインターフェイスの違いは、DB_Table_Database のメソッドでは最初のパラメータとして SQL を適用するテーブル名を指定する必要があるということです。
構文:
true|PEAR_Error insert(string $table, array $data) true|PEAR_Error delete(string $table, [string $where]) true|PEAR_Error update(string $table, array $data, [string $where]) |
DB_Table_Database のこれらのメソッドは、 対応する DB_Table のメソッドを内部でコールする単なるラッパーです。 その結果、DB_Table のサブクラスでこれらのメソッドを上書きして特定のテーブルの振る舞いを変更すると、 自動的に DB_Table_Database のメソッドの振る舞いも変わります。
DB_Table_Database の insert() メソッドや update() メソッドは、データベースのデータを実際に変更する前に外部キーの検証を行います。 また、外部キーの検証とトリガーアクションが有効な場合は 連鎖削除のような参照トリガーアクションをエミュレートすることもできます。 DB_Table の対応するメソッドは、 DB_Table が親の DB_Table_Database オブジェクトに追加されて (親オブジェクトへの参照が含まれて) そのアクションが親の DB_Table_Database オブジェクトで有効になっている場合に同じ動作をします。 外部キーの検証は、デフォルトでは無効になっています。 参照トリガーアクションはデフォルトで有効になっており、 データベースモデルで宣言されているすべてのアクションが有効となります。
insert() メソッドおよび update() メソッドは、外部キーの検証に失敗した場合やデータベースコマンドでエラーが発生した場合に PEAR_Error オブジェクトを返します。 また、ON DELETE アクションあるいは ON UPDATE アクションとして 'restrict' が宣言されて有効になっている場合に、 他のテーブルの外部キーから参照されている行を削除あるいは更新しようとした際にも PEAR_Error を返します。
DB_Table_Database の状態をページをまたがって管理するには、データベース全体を文字列にシリアライズし、 それをセッション変数やファイルあるいはデータベースに保存します。 シリアライズされた DB_Table_Database オブジェクトには、すべてのテーブルについてシリアライズされた情報が含まれます。 つまり、あとでデータベースを復元するときに必要な情報が含まれているというわけです。 シリアライズを行うには、PHP の serialize 関数を使用します。
<?php $db_serial = serialize($db); ?> |
<?php $db = unserialize($db_serial); $db->setDBconnection($DB_object); ?> |
DB_Table_Database オブジェクトがアンシリアライズされると、 子である DB_Table オブジェクトも DB_Table_Database::__wakeup() メソッドによってアンシリアライズされます。 DB_Table オブジェクトが DB_Table のサブクラスのインスタンスである場合、 テーブルをアンシリアライズする前にそのサブクラスの定義がメモリ上になければなりません。 これは、該当するクラスの定義を含むファイルを明示的にインクルードしておくか、 あるいは wake-up メソッドに組み込まれている auto-load の仕組みを使用します。
サブクラスの定義を自動で読み込ませるには、 各サブクラスをデフォルトのディレクトリ内の個別のファイルで定義する必要があります。 ファイル名は、クラス名に拡張子 '.php' を付加したものとなります。 アンシリアライズの際に "classname" という名前の DB_Table のサブクラスが必要となり、まだその定義がメモリ上になければ、 __wakeup() メソッドはこのディレクトリから "classname.php" というファイルをインクルードしようとします。
自動読み込みを機能させるには、get_class 関数で取得できるクラス名と同じ名前のファイルを用意する必要があります。 PHP 4 ではこれはクラス名を小文字にしたものとなりますが、 PHP 5 では大文字小文字がそのまま保持されます。
toXML() メソッドと fromXML() メソッドを使用すると、データベーススキーマを XML 文字列にシリアライズしたりその逆を行ったりすることができます。 fromXML() メソッドは simpleXML を使用して XML 文字列をパースします。したがって PHP 5 が必要となります (このクラスの中で唯一 PHP 4 では使用できないメソッドです)。
これらのメソッドで使用する XML スキーマは、現在の MDB2_Schema の DTD を拡張して外部キー参照を指定できるようにしたものです。 外部キー対応の拡張は、将来の MDB2_Schema のリリースに取り込まれる予定です。
toXML() メソッドは、データベース全体を XML 文字列で返します。つまりすべてのテーブルや外部キー参照を含んだもので、 次のように使用します。
<?php $xml_string = $db->toXML(); ?> |
<?php $db = DB_Table_Database::fromXML($xml_string); $db->setDBconnection($DB_object); ?> |
DB_Table_Database のメソッドの中には、 データベース内の全テーブル用に DB_Table のプロパティの値を設定するものもあります。 これらのメソッドは、どれも DB_Table の対応するメソッドと同じ名前とインターフェイスを持っています。
void autoValidInsert(bool $flag); void autoValidUpdate(bool $flag); void autoRecast(bool $flag); void autoInc(bool $flag); |
autoValidInsert メソッドおよび autoValidUpdate メソッドは、 データを追加したり更新したりする前のデータ型の検証機能を有効あるいは無効にします。 autoRecast メソッドは、データを追加したり更新したりする前の自動型変換機能を有効あるいは無効にします。 autoInc は、追加の際の $auto_inc_col カラムの値の PHP による自動インクリメント機能を有効あるいは無効にします。 この機能を有効にしても、追加する際にそのカラムを null のままにしておかない限りは自動インクリメントは行われないことに注意しましょう。