CXLIII. SDO 関数

導入

Service Data Objects (SDO) を使用すると、PHP アプリケーションから (データベースクエリ・XML ファイル・スプレッドシートなどの) さまざまな形式のデータへのアクセスが 同じインターフェイスで行えるようになります。

データソースにアクセスするには、それぞれのデータソースに対応した アクセス機能を提供するデータアクセスサービス (DAS) が必要となります。 PHP アプリケーションからは、データソース内のデータを表す SDO インスタンスを作成するために DAS を使用します。そうすると、 標準的な SDO インターフェイスを使用して SDO インスタンスの データに対する読み書きができるようになります。最後に、 変更されたデータを DAS でデータソースに書き込みます。 このデータソースは、通常は最初に作成したのと同じものとなります。

現在使用可能なデータアクセスサービスの詳細は、 データアクセスサービスの一覧 を参照ください。提供されている DAS 以外にも、SDO は 他のサービスを実装するためのインターフェイスも提供しています (詳細は SDO データアクセスサービス インターフェイス を参照ください)。

この拡張モジュールは、 Service Data Objects specification の概念に由来するものです。 Apache Tuscany SDO for C++ project を含んでいます。

Service Data Object の構造

Service Data Object のインスタンスは、データオブジェクトのツリーで 構成されています。このツリーは、データオブジェクト間の閉じた関係で 定義されます。例えば、Company (会社) データオブジェクトに いくつかの Department (部署) データオブジェクトが含まれていると すると、Company が Department を包含しているということになります。

SDO では、包含関係以外の関係もデータオブジェクトのツリー内で 保持することができます。例えば、ある Employee (従業員) データオブジェクトが、上司として別の Employee を参照していることが あるかもしれません。

データオブジェクト同士がお互いを参照するだけではなく、 オブジェクト以外のプロパティを保持することもできます。 例えば、Company データオブジェクトに文字列型のプロパティ "name" を含め、そこに会社名 ("Acme" など) を格納することもできます。

これらのデータオブジェクトのプロパティ、すなわち包含関係をもつもの、 包含関係を持たないもの、そしてプリミティブなプロパティは、 ひとつの値を持つこともあれば複数の値を持つこともあります。 上の例では、Departments は複数の値をとりますが Company の name はひとつの値しかとりません。

PHP では、SDO データオブジェクトは PHP のオブジェクトとして表されます。 データオブジェクトのプロパティへは、 オブジェクト構文あるいは連想配列形式の構文でアクセスすることができます。 後でこれらの例を示します。

要件

SDO 拡張モジュールを使用するには、PHP 5.1.0 以降が必要です。 また、libxml2 ライブラリも必要です。通常は、既に libxml2 はインストールされているでしょうが、もしインストールされていない場合は http://www.xmlsoft.org/ からダウンロードできます。

インストール手順

注意: 初期のバージョンの SDO 拡張モジュールは、XML DAS 用に別の共有ライブラリが必要でした。これは今は使われていないので、 php_sdo_das_xml.dllsdo_das_xml.so への参照を php.ini から削除してください。

Unix システム

  1. SDO コンポーネント、すなわち SDO コア・XML DAS およびリレーショナル DAS の最新版をダウンロード、 インストールするには、次のコマンドを使用します。 SDO を構成する 3 つのコンポーネントである SDO コア、XML DAS およびリレーショナル DAS は、ひとつの PECL プロジェクト Service Component Architecture (SCA) にまとめられており、SCA_SDO という名前になっています。つまり、以下のコマンドで、 SCA をダウンロードして SDO の全パーツをインストールすることができます。

    pecl install SCA_SDO

    このコマンドは SDO 共有ライブラリをビルドし、 SCA およびリレーショナル DAS の PHP ファイルをインストールします。

    最新のベータ版を使用するには、代わりに次のコマンドを使用します。

    pecl install SCA_SDO-beta

  2. pecl コマンドは、SDO モジュールを自動的に PHP 拡張モジュールディレクトリにインストールします。 SDO 拡張モジュールを有効にするには、以下の行を php.ini に追加しなければなりません。

    extension=sdo.so

    PECL パッケージのビルド方法についての詳細は、マニュアルの PECL 拡張モジュールのインストール を参照ください。

Windows

  1. SDO の最新版の DLL は、 php_sdo.dll からダウンロードできます。

    現在は、pecl4win では安定リリース版のバイナリが提供されていないことに注意しましょう。 最新版のみがダウンロード可能となっています。

  2. pecl コマンドは、SDO モジュールを自動的に PHP 拡張モジュールディレクトリにインストールします。 SDO 拡張モジュールを有効にするには、以下の行を php.ini に追加しなければなりません。

    extension=php_sdo.dll

  3. リレーショナル DAS をダウンロード、インストールするには、 以下のコマンドを実行します。

    pecl install -B sdo

    リレーショナル DAS は PHP で書かれています。 sdo/DAS/Relational を含むディレクトリを指すように php.iniinclude_path を設定しなければなりません。

Linux での SDO のビルド

この節では、Linux 上で SDO コアおよび XML DAS をビルドする方法を 説明します。これを知る必要があるのは、CVS からチェックアウトした 最新バージョンをビルドしたい場合のみです。

  1. 拡張モジュールのメインディレクトリに移動します。 cd < sdo のコードがある場所 >

  2. phpize を実行します。これにより、 SDO をコンパイルするための環境を設定します。

  3. 次に ./configure; make; make install を実行します。 拡張モジュールをインストールするには、root としてログインする 必要があることに注意しましょう。

  4. php.ini ファイルに extension=sdo.so を追加することで、このモジュールが PHP に読み込まれるようにします。

データアクセスサービス

以下の表で、現在提供されている SDO データアクセスサービスの 一覧を示します。

DAS 名説明
SDO_DAS_XML XML データアクセスサービスは、SDO を XML ドキュメントとして 読み書きします。
SDO_DAS_Relational PDO を基にしたデータアクセスサービスで、SDO をリレーショナル データベースとして読み書きします。同時更新に対しては 楽観的な実装となっています。

制限事項

実装上の制限

現在の SDO の実装には、以下の制限があります。

  1. マルチバイト文字セットはサポートしていません。 コミュニティの要望があれば、Unicode 対応版の PHP で対応するかもしれません。 Unicode 関数 を参照ください。

SDO の制限

現在の PHP の実装では、以下の SDO 2.0 の概念はサポートされていません。 将来これらのすべてが実装されるとは限りません。実装されるかどうかは コミュニティの要望があるかどうかによります。

  1. 双方向のリレーション

  2. 型およびプロパティのエイリアス

  3. 読み込み専用のプロパティ

  4. SDO 2.0 で定義されているヘルパークラスは、直接には実装されていません。 しかし、同等の機能がより PHP らしい方法で提供されています。 例えば、CopyHelper::copy() の機能については、 データオブジェクトに PHP の clone キーワードを適用することで実現できます。

以下の例では、XML データアクセスサービスを使用して、 下のスキーマおよびインスタンスをもとに作成した SDO の使用を想定しています。

以下で説明しているインスタンスドキュメントは、 'MegaCorp' という会社を扱っています。この会社には 'Advanced Technologies' という名前の部署がひとつあります。 Advanced Technologies 部門には 3 人の従業員がいます。 この会社の employeeOfTheMonth (今月の従業員) は、 2 人目の従業員である 'Jane Doe' を指しています。

<?xml version="1.0" encoding="UTF-8" ?>
<company xmlns="companyNS" name="MegaCorp"
  employeeOfTheMonth="E0003">
  <departments name="Advanced Technologies" location="NY" number="123">
    <employees name="John Jones" SN="E0001"/>
    <employees name="Jane Doe" SN="E0003"/>
    <employees name="Al Smith" SN="E0004" manager="true"/>
  </departments>
</company>

このスキーマのルート要素は company です。company は departments を含んでおり、個々の department は employees を含んでいます。 各要素はいくつかの属性を保持しており、ここに名前やシリアル番号などを保存します。 最後に、company は IDREF 属性を保持しており、 特定の従業員を 'employeeOfTheMonth' として参照しています。

<xsd:schema
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:sdo="commonj.sdo"
  xmlns:sdoxml="commonj.sdo/xml"
  xmlns:company="companyNS"
  targetNamespace="companyNS">
  <xsd:element name="company" type="company:CompanyType"/>
  <xsd:complexType name="CompanyType">
    <xsd:sequence>
      <xsd:element name="departments" type="company:DepartmentType"
        maxOccurs="unbounded"/>
    </xsd:sequence>
    <xsd:attribute name="name" type="xsd:string"/>
    <xsd:attribute name="employeeOfTheMonth" type="xsd:IDREF"
      sdoxml:propertyType="company:EmployeeType"/>
  </xsd:complexType>
  <xsd:complexType name="DepartmentType">
    <xsd:sequence>
      <xsd:element name="employees" type="company:EmployeeType"
       maxOccurs="unbounded"/>
    </xsd:sequence>
    <xsd:attribute name="name" type="xsd:string"/>
    <xsd:attribute name="location" type="xsd:string"/>
    <xsd:attribute name="number" type="xsd:int"/>
  </xsd:complexType>
  <xsd:complexType name="EmployeeType">
    <xsd:attribute name="name" type="xsd:string"/>
    <xsd:attribute name="SN" type="xsd:ID"/>
    <xsd:attribute name="manager" type="xsd:boolean"/>
  </xsd:complexType>
</xsd:schema>

XML データアクセスサービスは、スキーマを SDO に関連付けます。 "name" のような属性はプリミティブプロパティに、 一連の employees は複数の値をとる包含関係に、といったようになります。 包含関係は、複合型の中に別の複合型を含めることで表され、 非包含関係は ID や IDREF に特別な属性 sdoxml:propertyType を指定して表されることに注意しましょう。

プロパティの値の設定および取得

以下の例では、上で示したスキーマおよびインスタンスドキュメントをもとに 作成したデータオブジェクトツリーのルート要素が $company に入っているものとして考えます。

例 1. プロパティ名を使用したアクセス

データオブジェクトのプロパティへは、通常のオブジェクトの プロパティにアクセスするのと同じ構文でアクセス可能です。 以下の例では、会社の名前を 'Acme' に変更します。

<?php
  $company
->name = 'Acme';
?>

例 2. 配列のインデックスを使用したプロパティへのアクセス

連想配列形式の構文を使用して、プロパティにアクセスすることもできます。 最も簡単な負尾法は、プロパティ名を配列のインデックスとして使用する方法です。 例えば、以下の例では会社の名前を設定してから「今月の従業員」を取得しています。

<?php
  $company
['name'] = 'UltraCorp';
  
$eotm = $company['employeeOfTheMonth'];
?>

例 3. データオブジェクトの繰り返し処理

foreach を使用することにより、データオブジェクトのプロパティを 順に処理していくことができます。以下の例では、 今月の従業員のプロパティを順に処理します。

<?php
  $eotm
= $company->employeeOfTheMonth;
  foreach (
$eotm as $name => $value) {
      echo
"$name: $value\n";
  }
?>

出力は以下のようになります。

name: Jane Doe
SN: E0003

'manager' プロパティは表示されません。なぜなら設定されていないからです。

例 4. 多くの値をとりうるプロパティへの名前によるアクセス

多くの値をとりうるデータオブジェクトのプロパティへのアクセスも、 オブジェクトのプロパティに対するアクセス構文でアクセスできます。 例えば部署の一覧を取得するにはこのようにします。

<?php
  $departments
= $company->departments;
?>

例 5. 多くの値をとりうる要素へのアクセス

配列の構文を使用することで、多くの値をとりうる要素における 個々の要素にアクセスすることが可能です。以下の例では、 会社の中の最初の部署にアクセスしています。

<?php
  $ad_tech_dept
= $company->departments[0];
?>

例 6. 多くの値をとりうるプロパティの順次処理

foreach を使用して、多くの値をとりうるプロパティを順に処理することができます。 会社の各部門を順に処理するにはこのようにします。

<?php
  
foreach ($company->departments as $department) {
    
// ...
  
}
?>

繰り返しのたびに、次の部署が変数 $department に代入されます。

例 7. 連結されたプロパティへのアクセス

プロパティへの参照を、ひとつの行に連結することができます。 以下の例では、最初の部署の名前を設定し、取得しています。

<?php
  $company
->departments[0]->name = 'Emerging Technologies';
  
$dept_name = $company->departments[0]->name;
?>

同じことを連想配列構文で行うと、このようになります。

<?php
  $company
['departments'][0]['name'] = 'Emerging Technologies';
  
$dept_name = $company['departments'][0]['name'];
?>

どちらの場合でも、dept_name の内容は 'Emerging Technologies' となります。

例 8. XPath によるナビゲーション

連想配列のインデックスとして、XPath 風の式を使用することができます。 実際に使用できる式は、XPath の拡大サブセットです。

多くの値をとりうるプロパティの表す方法として、 2 通りの方法がサポートされています。 最初の方法は、1 から始まる標準的な XPath の配列構文を使用するものです。 もうひとつは、SDO で XPath を拡張した構文で、 ゼロから始まるインデックスを使用します。 標準的な構文は以下のようになります。

<?php
  $jane_doe
= $company["departments[1]/employees[2]"];
?>

そして SDO の拡張版 XPath 構文はこのようになります。

<?php
  $jane_doe
= $company["departments.0/employees.1"];
?>

どちらの例でも、最初の部署の 2 番目の従業員を取得します。

例 9. XPath による問い合わせ

XPath を使用して、インスタンスのデータ内のデータオブジェクトを 検索することができます。以下の例では、部署 'Advanced Technologies' の manager を取得しています。

<?php
$ad_tech_mgr
=
  
$company["departments[name='Advanced Technologies']/employees[manager=true]"];
?>

例 10. 子オブジェクトの作成

データオブジェクトは、自分自身の中に子オブジェクトを保持することが できます。子データオブジェクトは自動的にデータグラフの一員となります。 以下の例では、部署 'Advanced Technologies' に新しい従業員を追加しています。

<?php
  $ad_tech_dept
= $company["departments[name='Advanced Technologies']"];
  
$new_hire = $ad_tech_dept->createDataObject('employees');
  
$new_hire->name = 'John Johnson';
  
$new_hire->SN = 'E0005';
  
$new_hire->manager = false;
?>

例 11. プリミティブなプロパティの開放

データオブジェクトに項目が登録されているかどうかを確かめたり 項目を削除したりする際には、それぞれ isset() および unset() 関数が使用可能です。

以下の例は、最初の部署の名前を消去します。

<?php
  
unset($company->departments[0]->name);
?>

例 12. データオブジェクトの開放

unset は、ツリーからデータオブジェクトを削除する場合にも使用できます。 以下の例は、John Jones を会社から削除します。

<?php
  
unset($company->departments[0]->employees[0]);
?>

例 13. 参照されているデータオブジェクトの開放

以下の例では、会社から「今月の従業員」を削除します。 もしこれらの間に包含関係があった場合、参照先の従業員も 削除されてしまいます (その月の一番優秀な従業員を毎月クビにしていく なんてバカなことは、普通はしないでしょう!)。 しかし実際にはこれらは包含関係ではないので、参照先の 従業員は会社の中の部署の中に残り続けます。ただ、 employeeOfTheMonth プロパティを通じてはアクセスできなくなります。

<?php
  
if (isset($company->employeeOfTheMonth)) {
    unset(
$company->employeeOfTheMonth);
  }
?>

例 14. プロパティのインデックスを使用したアクセス

配列構文を使用して、プロパティのインデックス経由で データオブジェクトのプロパティにアクセスすることができます。 プロパティのインデックスは、モデル (この場合は xml スキーマ) 内でそのプロパティの定義が現れる位置となります。 上のスキーマの例では、会社の名前が company の 2 番目の属性であることがわかります (SDO のインターフェイスは、 XML の要素と属性を区別しません)。以下の例では、 会社の名前を 'Acme' に設定します。これは プロパティ名を使用したアクセス と同じ結果となります。

<?php
  $company
[1] = 'Acme';
?>

このようにインデックスを直接使用すると、後で破綻してしまう可能性があります。 通常はプロパティ名を使用する方式を推奨します。 しかし、時にはインデックスによるアクセスが必要になる場合もあるでしょう。

シーケンスデータオブジェクトの使用

シーケンスデータオブジェクトは、データオブジェクト内のさまざまな プロパティの並び順を追跡する SDO です。ここには、非構造化 テキスト要素 (SDO のいずれのプロパティにも属さないテキスト要素) を含めることも可能です。シーケンスデータオブジェクトは、 非構造化テキストを許可 (つまり、mixed=true である) したり、要素が交互に現れる (<A/><B/><A/>) ような XML 文書を扱う場合に有用です。 これは、例えば order に choice を指定した複合型の要素に対して スキーマで maxOccurs>1 を定義している場合などに発生します。

以下の例では、XML データアクセスサービスを使用して、 下のスキーマおよびインスタンスをもとに作成した SDO の使用を想定しています。

このスキーマでは、手紙の書式を定義しています。letter (手紙) には オプションで 3 つのプロパティ date (日付)、firstName (名前)、 および lastName (苗字) を含めることが可能です。このスキーマでは mixed="true" としていますが、これは 3 つのプロパティの間に非構造化テキストをちりばめることが できるということを意味します。

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:letter="http://letterSchema"
  targetNamespace="http://letterSchema">
  <xsd:element name="letters" type="letter:FormLetter"/>
  <xsd:complexType name="FormLetter" mixed="true">
    <xsd:sequence>
      <xsd:element name="date" minOccurs="0" type="xsd:string"/>
      <xsd:element name="firstName" minOccurs="0" type="xsd:string"/>
      <xsd:element name="lastName" minOccurs="0" type="xsd:string"/>
    </xsd:sequence>
  </xsd:complexType>
</xsd:schema>

以下が、手紙のインスタンスです。これには 3 つのプロパティ date、firstName および lastName が含まれており、非構造化 テキスト要素として住所と本文が含まれています。

<letter:letters xmlns:letter="http://letterSchema">
  <date>March 1, 2005</date>
  Mutual of Omaha
  Wild Kingdom, USA
  Dear
  <firstName>Casy</firstName>
  <lastName>Crocodile</lastName>
  Please buy more shark repellent.
  Your premium is past due.
</letter:letters>

このインスタンスが読み込まれると、letter データオブジェクトの シーケンス番号およびプロパティ番号は以下の表のようになります。

シーケンスのインデックスプロパティのインデックス:名前
00:dateMarch 1, 2005
1-Mutual of Omaha
2-Wild Kingdom, USA
3-Dear
41:firstNameCasy
52:lastNameCrocodile
6-Please buy more shark repellent.
7-Your premium is past due.

シーケンス番号の整合性を保つため、シーケンスデータオブジェクトの 操作には SDO_Sequence インターフェイスを使用しなければなりません。 これにより、データオブジェクトに対しての操作を プロパティのインデックスではなくシーケンスのインデックスを使用して 行えるようになります (上の表を参照ください)。 以下の例では、letter のインスタンスが データオブジェクト $letter として 読み込まれているものと仮定します。

例 15. SDO_Sequence インターフェイスの取得

データオブジェクトのシーケンスを取得するには getSequence() メソッドを使用します。 以下の例では、letter データオブジェクトのシーケンスを取得します。

<?php
  $letter_seq
= $letter->getSequence();
?>

これ以降の例では、letter データオブジェクトのシーケンスが 変数 $letter_seq に代入されているものとします。

例 16. シーケンスの値の取得/設定

シーケンスのインデックスを使用することで、(非構造化 テキストも含め) それぞれの値を取得したり設定したりすることが可能です。 以下の例では、ファーストネームを 'Snappy' に変更して シーケンスの最後の値 (非構造化テキスト 'Your premium is past due.') を取得します。

<?php
  $letter_seq
[4] = 'Snappy';
  
$text = $letter_seq[count($letter_seq) - 1];
?>

例 17. シーケンスの繰り返し処理

foreach を使用して、個々のシーケンス値について処理を繰り返すことが できます。以下の例では、シーケンス順に個々の値を処理します。

<?php
  
foreach ($letter->getSequence() as $value) {
    
// ...
  
}
?>

例 18. シーケンスとデータオブジェクトの比較

データオブジェクトのインターフェイスから設定した値は、シーケンスの 一部とはならないことがあります。データオブジェクト経由で値を 設定した場合、そのプロパティが既にシーケンスに組み込まれていた 場合にのみシーケンスからアクセス可能となります。 以下の例では、データオブジェクト経由で lastName を設定して それをシーケンスから取得しています。これがうまくいくのは、 lastName が既にシーケンス内に存在するからです。もしこれが 事前に設定されていなかった場合、lastName には 'Smith' が 設定されますが、それはシーケンスの一部とはなりません。

<?php
  $letter
[2] = 'Smith';
  
$last_name = $letter_seq[5];
?>

例 19. シーケンスへの追加

シーケンスに新しい値を追加するには SDO_Sequence::insert() メソッドを使用します。以下の例では、プロパティ 'firstName' および 'lastName' が最初に削除されているものと仮定します。

<?php
  
// シーケンスに firstName を追加します
  // 値: 'Smith'
  // シーケンスのインデックス: NULL (追加)
  // プロパティ ID: 1 (firtName プロパティのインデックス)
  
$letter_seq->insert('Smith', NULL, 1);

  
// シーケンスに lastName を追加します
  // 値: 'Jones'
  // シーケンスのインデックス: NULL (追加)
  // プロパティ ID: 'lastName' (lastName プロパティの名前)
  
$letter_seq->insert('Jones', NULL, 'lastName');

  
// 非構造化テキストを追加します
  // 値: 'Cancel Subscription.'
  // シーケンスのインデックス: 省略 (追加)
  // プロパティ ID: 省略 (非構造化テキスト)
  
$letter_seq->insert('Cancel Subscription.');

  
// 非構造化テキストを間に挿入します。それ以降のシーケンス値は
  // ひとつずれます。
  // 値: 'Care of:'
  // シーケンスのインデックス: 1 (2 番目の要素として挿入する)
  // プロパティ ID: 省略 (非構造化テキスト)
  
$letter_seq->insert('Care of:', 1);
?>

例 20. シーケンスからの削除

シーケンスに項目が登録されているかどうかを確かめたり シーケンスから項目を削除したりする際には、それぞれ isset() および unset() 関数が使用可能です (注意: unset() は、現時点では値を データオブジェクト内に残します。しかし、この挙動はおそらく今後 変更され、データオブジェクトからもデータを削除することに なるでしょう)。シーケンスの挙動は、リスト構造に似ています。 そのため、シーケンスの途中の項目を削除すると、それ以降の インデックスがひとつずつ小さいほうにずれます。以下の例では、 インデックスの最初の要素が存在するかどうか調べ、存在する場合に それを削除しています。

<?php
  
if (isset($letter_seq[0])) {
    unset(
$letter_seq[0]);
  }
?>

サービスデータオブジェクトへのリフレクション

SDO は、自分自身を作成するもととなったオブジェクト (モデル) の構造を知っています。例えば、上の Company XML スキーマ を使用して 作成した Company SDO には DepartmentType データオブジェクトしか 含めることはできず、同様に DepartmentType データオブジェクトには EmployeeType データオブジェクトしか含めることはできません。

実行時にモデルの情報にアクセスできると、以下のような利点があります。 例えば、データオブジェクトに値を設定するためのユーザインターフェイスを 自動的に作成することができます。モデルの情報にアクセスするには、 リフレクションを使用します。

例 21. データオブジェクトへのリフレクション

以下の例では、空の Employee データオブジェクトへのリフレクションの 方法を示します。

<?php
  
// employee データオブジェクトを (例えば XML データアクセスサービスなどから) 作成します
  
$employee = ...;
  
$reflection = new SDO_Model_ReflectionDataObject($employee);
  print(
$reflection);
?>

上の例の出力は以下となります。

object(SDO_Model_ReflectionDataObject)#4 { - ROOT OBJECT - Type {
companyNS:EmployeeType[3] { commonj.sdo:String $name;
commonj.sdo:String $SN; commonj.sdo:Boolean $manager; } }

SDO_Model_ReflectionDataObject に対して print を使用すると、 データオブジェクトのモデルを出力します。この出力結果から、 companyNS:EmployeeType 型には 3 つのプロパティがあることや それぞれのプロパティの名前と型を知ることができます。 プリミティブ型は、SDO の型として表示されることに注意しましょう (例: commonj.sdo namespace, String type)。これは SDO モデルであり、 アプリケーションからは PHP の同等の型 (例: string および boolean) として扱えることを知っておくとよいでしょう。

例 22. 型情報へのアクセス

リフレクションを使用して、データオブジェクトの型情報を取得することが できます。以下の例では、まず型がプリミティブ型ではなく データオブジェクトに対応するものであることを確認し、各プロパティの 名前を書き出しています ($type および $property は、それぞれ SDO_Model_Type および SDO_Model_Property オブジェクトです)。

<?php
    
// employee データオブジェクトを (例えば XML データアクセスサービスなどから) 作成します
    
$employee = ...;
    
$reflection = new SDO_Model_ReflectionDataObject($employee);
    
$type = $reflection->getType();
    if (!
$type->isDataType()) {
        foreach (
$type->getProperties() as $property) {
            print
$property->getName() . "\n";
        }
    }
?>

上の例の出力は以下となります。

name
SN
manager

定義済みクラス

SDO は、3 つの系統のインターフェイスから構成されています。ひとつめは 典型的な SDO アプリケーションで使用されるインターフェイスをカバーする もので、これらには 'SDO_' という名前がつけられています。2 番目は データオブジェクトのモデルを扱うためのもので、これらには 'SDO_Model_' という名前がつけられています。最後はデータアクセスサービスで 使用されるもので、これらには 'SDO_DAS_' という名前がつけられています。 SDO を使用するほとんどの人は、'SDO_Model_' や 'SDO_DAS_' を使用したり理解したりする必要はないでしょう。

SDO API

SDO_DataObject

データオブジェクトを操作する際のメインとなるインターフェイスです。 以下で説明するメソッドに加え、SDO_DataObject は ArrayAccess、SDO_PropertyAccess (プロパティへのアクセスのために __get() / __set() メソッドをオーバーロードします)、 Iterator および Countable インターフェイスを継承します。

メソッド

  • getSequence - データオブジェクトのシーケンスを取得する

  • createDataObject - 子データオブジェクトを作成する

  • clear - データオブジェクトのプロパティの設定を解除する

  • getContainer - このオブジェクトのコンテナ (あるいは「親」) を取得する

  • getTypeName - このデータオブジェクトの型の名前を取得する

  • getTypeNamespaceURI - このデータオブジェクトの型の名前空間 URI を取得する

SDO_Sequence

シーケンスデータオブジェクトが、データオブジェクトのプロパティの 並び順を保持したままアクセスをおこなったり 非構造化テキストを許可したりする際に使用するインターフェイスです。 SDO_Sequence は、インデックスが常に連続した数となるようにします。 そのため、要素を挿入したり削除したりすると、その他の要素のインデックスが 増減します。以下で説明するメソッドに加え、SDO_Sequence は ArrayAccess、Iterator および Countable インターフェイスを 継承しています。

メソッド

  • getProperty - シーケンスのインデックスからプロパティを取得する

  • move - 指定した要素を、現在のプロパティインデックスから別の位置に移動する

  • insert - シーケンスに新しい値を挿入する

SDO_List

複数の値を保持するプロパティを操作するためのインターフェイスです。 以下に挙げるメソッドに加え、SDO_List は ArrayAccess、 Iterator および Countable を継承しています。 SDO_List は、常にインデックスが連続した数となるようにします。 そのため、要素を挿入したり削除したりすると 他の要素のインデックスが変化します。

メソッド

  • insert - 新しい値をリストに挿入する

SDO_DataFactory

データオブジェクトを作成するためのインターフェイスです。 ファクトリのモデルに値を設定する (すなわち、作成可能なデータ オブジェクトの型および構造情報をもとにデータファクトリを設定する) のはデータアクセスサービスの役目です。また、オプションとして SDO_DataFactory インターフェイスのインスタンスを返すか、 それを実装します。

メソッド

  • create - 新しいデータオブジェクトを作成する

SDO_Exception

SDO_Exception は、呼び出し元の要求を完了させられなかった際にスローされます。 SDO_Exception のサブクラスには以下のようなものがあります。

  • SDO_PropertyNotSetException - 指定されたプロパティは存在するが、まだ値が設定されていません。 あるいはデフォルト値が設定されていません。

  • SDO_PropertyNotFoundException - 指定されたプロパティはデータオブジェクトの型の一部ではありません。

  • SDO_TypeNotFoundException - 指定された名前空間 URI あるいは型名が見つかりません。

  • SDO_InvalidConversionException - 代入時に、型の変換を行うことができません。

  • SDO_IndexOutOfBoundsException - データオブジェクトやシーケンス、リストにおける数値インデックスが 有効な範囲にありません。

  • SDO_UnsupportedOperationException - その操作が許可されていないため、要求を完了できませんでした。 例えば読み込み専用のプロパティに値を設定しようとした場合などです。

メソッド

組み込みの Exception クラスから継承したものに加え、次のメソッドが追加されています。

  • getCause - この SDO_Exception の原因を取得する

SDO リフレクション API

SDO_Model_ReflectionDataObject

データオブジェクトのインスタンス自身について、モデルの型や プロパティの情報を取得するためのインターフェイスです。 PHP 5 で使用可能となったリフレクションパターンに従うように 設計されています。

コンストラクタ

  • __construct - 新しい SDO_Model_ReflectionDataObject を作成する

メソッド

  • export - データオブジェクトを表す文字列を取得する

  • getType - データオブジェクトの SDO_Model_Type を取得する

  • getInstanceProperties - データオブジェクトのインスタンスのプロパティを取得する

  • getContainmentProperty - データオブジェクトとの包含関係を定義しているプロパティを取得する

SDO_Model_Type

データオブジェクトの型に関する情報を取得するための インターフェイスです。このインターフェイスは、型の名前および 名前空間 URI・オープン型のデータを許可するかどうかなどを 調べるために使用します。

メソッド

  • getName - 型の名前を取得する

  • getNamespaceURI - 型の名前空間 URI を取得する

  • isInstance - データオブジェクトが特定の型のインスタンスであるかどうかを調べる

  • getProperties - 型のプロパティを取得する

  • getProperty - 型のプロパティを取得する

  • isDataType - この型が基本的なスカラー型であるかどうかを調べる

  • isSequencedType - この型がシーケンス型であるかどうかを調べる

  • isOpenType - この型がオープン型であるかどうかを調べる

  • isAbstractType - この型が抽象型であるかどうかを調べる

  • getBaseType - この型の基底型を (もし存在すれば) 取得する

SDO_Model_Property

データオブジェクトのプロパティに関する情報を取得するための インターフェイスです。このインターフェイスは、プロパティの型・ デフォルト値の存在・包含関係の有無・カーディナリティなどを 調べるために使用します。

メソッド

  • getName - プロパティの名前を取得する

  • getType - プロパティの型を取得する

  • isMany - プロパティが複数の値を保持するかどうかを調べる

  • isContainment - プロパティが包含関係を保持するかどうかを調べる

  • getContainingType - このプロパティを含んでいる型を取得する

  • getDefault - プロパティのデフォルト値を取得する

SDO データアクセスサービス 開発者用インターフェイス

SDO_DAS_DataObject

データアクセスサービスが、データオブジェクトの SDO_DAS_ChangeSummary にアクセスするためのインターフェイスです。これは、変更した内容を データベースに書き戻す際に、データアクセスサービスがデータの 衝突を調べるために使用されます。

メソッド

SDO_DAS_ChangeSummary

データオブジェクトの変更履歴にアクセスするためのインターフェイスです。 ログ取得が有効になってからデータオブジェクトに発生したあらゆる変更が、 変更内容に含まれます。削除あるいは修正の場合は、変更前の情報も保持されます。

ログ取得が有効になっていない場合、ログ取得が無効にされた時点までの 変更内容が保存されます。ログ取得を再開すると、過去の変更内容は消去されます。 これは、変更内容を DAS で書き出した後にデータオブジェクトを 再利用する場合に有用です。

メソッド

  • beginLogging - データオブジェクトの変更履歴のログ取得を開始する

  • endLogging - データオブジェクトの変更履歴のログ取得を終了する

  • isLogging - ログ取得が有効になっているかどうかを調べる

  • getChangedDataObjects - 変更されたデータオブジェクトの一覧を取得する

  • getChangeType - データオブジェクトの変更の型を取得する

  • getOldValues - データオブジェクトの変更前の値を取得する

  • getOldContainer - 削除されたデータオブジェクトの削除前のコンテナを取得する

SDO_DAS_Setting

プロパティの古い値にアクセスするためのインターフェイスです。 設定の一覧は、 getOldValues() で返されます。 .

メソッド

  • getPropertyIndex - 変更されたプロパティのプロパティインデックスを取得する

  • getPropertyName - 変更されたプロパティのプロパティ名を取得する

  • getValue - 変更されたプロパティの古い値を取得する

  • getListIndex - 複数の値を持つプロパティだった場合に、古い値のインデックスの 一覧を取得する

  • isSet - 変更前に、プロパティが設定されていたかどうかを調べる

SDO_DAS_DataFactory

SDO_DataObject のモデルを作成するインターフェイスです。 SDO_DAS_DataFactory は抽象クラスで、それを実装した具象データファクトリを 返すスタティックメソッドを提供します。この実装クラスを使用して、 データアクセスサービスが SDO モデルを作成します。 例えばリレーショナルデータアクセスサービスは、リレーショナル データベースのスキーマをもとにして SDO_DAS_DataFactory モデルを 作成し、そこに値を設定します。

メソッド

  • getDataFactory - 具象データファクトリのインスタンスを取得するためのスタティックメソッド

  • addType - SDO モデルに新しい型を追加する

  • addPropertyToType - SDO モデルの型定義に新しいプロパティを追加する

定義済み定数

以下の定数が定義されています。 この関数の拡張モジュールが PHP 組み込みでコンパイルされているか、 実行時に動的にロードされている場合のみ使用可能です。

SDO_DAS_ChangeSummary::NONE=0 (integer)

変更の型 'none (変更していない)' を表します。

SDO_DAS_ChangeSummary::MODIFICATION=1 (integer)

変更の型 'modification (修正)' を表します。

SDO_DAS_ChangeSummary::ADDITION=2 (integer)

変更の型 'addition (追加)' を表します。

SDO_DAS_ChangeSummary::DELETION=3 (integer)

変更の型 'deletion (削除)' を表します。

目次
SDO_DAS_ChangeSummary::beginLogging --  変更内容の記録を開始する
SDO_DAS_ChangeSummary::endLogging --  変更内容の記録を終了する
SDO_DAS_ChangeSummary::getChangeType --  SDO_DataObject への変更の型を取得する
SDO_DAS_ChangeSummary::getChangedDataObjects --  変更内容から、変更されたデータオブジェクトを取得する
SDO_DAS_ChangeSummary::getOldContainer --  削除された SDO_DataObject の削除前のコンテナを取得する
SDO_DAS_ChangeSummary::getOldValues --  変更された SDO_DataObject の変更前の値を取得する
SDO_DAS_ChangeSummary::isLogging --  変更内容が記録されるようになっているかどうかを調べる
SDO_DAS_DataFactory::addPropertyToType --  型にプロパティを追加する
SDO_DAS_DataFactory::addType --  モデルに新しい型を追加する
SDO_DAS_DataFactory::getDataFactory --  データファクトリのインスタンスを取得する
SDO_DAS_DataObject::getChangeSummary --  データオブジェクトの変更内容を取得する
SDO_DAS_Setting::getListIndex --  複数の値を持つプロパティのインデックスを取得する
SDO_DAS_Setting::getPropertyIndex --  変更されたプロパティのプロパティインデックスを取得する
SDO_DAS_Setting::getPropertyName --  変更されたプロパティのプロパティ名を取得する
SDO_DAS_Setting::getValue --  変更されたプロパティの変更前の値を取得する
SDO_DAS_Setting::isSet --  変更前にプロパティが設定されていたかどうかを調べる
SDO_DataFactory::create --  SDO_DataObject を作成する
SDO_DataObject::clear --  SDO_DataObject のプロパティを消去する
SDO_DataObject::createDataObject --  新しい子 SDO_DataObject を作成する
SDO_DataObject::getContainer --  データオブジェクトのコンテナを取得する
SDO_DataObject::getSequence --  データオブジェクトのシーケンスを取得する
SDO_DataObject::getTypeName --  データオブジェクトの型の名前を取得する
SDO_DataObject::getTypeNamespaceURI --  このデータオブジェクトの型の名前空間 URI を取得する
SDO_Exception::getCause --  例外の原因を取得する
SDO_List::insert --  リストに挿入する
SDO_Model_Property::getContainingType --  このプロパティを含む SDO_Model_Type を取得する
SDO_Model_Property::getDefault --  プロパティのデフォルト値を取得する
SDO_Model_Property::getName --  SDO_Model_Property の名前を取得する
SDO_Model_Property::getType --  プロパティの SDO_Model_Type を取得する
SDO_Model_Property::isContainment --  プロパティが包含関係を定義しているかどうかを調べる
SDO_Model_Property::isMany --  プロパティが複数の値を持つかどうかを調べる
SDO_Model_ReflectionDataObject::__construct --  SDO_Model_ReflectionDataObject を作成する
SDO_Model_ReflectionDataObject::export --  SDO_DataObject を表す文字列を取得する
SDO_Model_ReflectionDataObject::getContainmentProperty --  データオブジェクトとの包含関係を定義しているプロパティを取得する
SDO_Model_ReflectionDataObject::getInstanceProperties --  SDO_DataObject のインスタンスプロパティを取得する
SDO_Model_ReflectionDataObject::getType --  SDO_DataObject の SDO_Model_Type を取得する
SDO_Model_Type::getBaseType --  この型の基底型を取得する
SDO_Model_Type::getName --  型の名前を取得する
SDO_Model_Type::getNamespaceURI --  型の名前空間 URI を取得する
SDO_Model_Type::getProperties --  型で定義されている SDO_Model_Property オブジェクトを取得する
SDO_Model_Type::getProperty --  型の SDO_Model_Property を取得する
SDO_Model_Type::isAbstractType --  この SDO_Model_Type が抽象データ型であるかどうかを調べる
SDO_Model_Type::isDataType --  この SDO_Model_Type がプリミティブなデータ型であるかどうかを調べる
SDO_Model_Type::isInstance --  SDO_DataObject が、この SDO_Model_Type のインスタンスであるかどうかを調べる
SDO_Model_Type::isOpenType --  この型がオープン型であるかどうかを調べる
SDO_Model_Type::isSequencedType --  この型がシーケンス型であるかどうかを調べる
SDO_Sequence::getProperty --  指定したシーケンスインデックスに対応するプロパティを返す
SDO_Sequence::insert --  シーケンスに挿入する
SDO_Sequence::move --  シーケンス上の指定した位置に項目を移動する