PHP Manual

3 つのクラスを定義し、各々に別々のストレージメソッドを実装します。

例1 storage_classes.inc

<?php
class FileStorage {
   var 
$data;

   function 
FileStorage($data
   {
       
$this->data $data;
   }
   
   function 
write($name
   {
       
$fp fopen(name"w");
       
fwrite($fp$this->data);
       
fclose($data);
   }
}

class 
WDDXStorage {
   var 
$data;
   var 
$version "1.0";
   var 
$_id// "private" 変数

   
function WDDXStorage($data
   {
       
$this->data $data;
       
$this->_id $this->_genID();
   }

   function 
store() 
   {
       if (
$this->_id) {
           
$pid wddx_packet_start($this->_id);
           
wddx_add_vars($pid"this->data");
           
$packet wddx_packet_end($pid);
       } else {
           
$packet wddx_serialize_value($this->data);
       }
       
$dbh dba_open("varstore""w""gdbm");
       
dba_insert(md5(uniqid(""true)), $packet$dbh);
       
dba_close($dbh);
   }

   
// プライベートメソッド
   
function _genID() 
   {
       return 
md5(uniqid(rand(), true));
   }
}

class 
DBStorage {
   var 
$data;
   var 
$dbtype "mysql";

   function 
DBStorage($data
   {
       
$this->data $data;
   }

   function 
save() 
   {
       
$dbh mysql_connect();
       
mysql_select_db("storage"$dbh);
       
$serdata serialize($this->data);
       
mysql_query("insert into vars ('$serdata',now())"$dbh);
       
mysql_close($dbh);
   }
}

?>

この定義済みクラスを用いていくつかのオブジェクトをインスタンス化し、 集約や集約の解除を行いつつ随時オブジェクトの情報を出力します。

例2 test_aggregation.php

<?php
include "storageclasses.inc";

// ユーティリティ関数

function p_arr($arr
{
   foreach (
$arr as $k => $v)
       
$out[] = "\t$k => $v";
   return 
implode("\n"$out);
}

function 
object_info($obj
{
   
$out[] = "クラス: " get_class($obj);
   foreach (
get_object_vars($obj) as $var=>$val) {
       if (
is_array($val)) {
           
$out[] = "プロパティ: $var (array)\n" p_arr($val);
       } else {
           
$out[] = "プロパティ: $var = $val";
       }
   }
   foreach (
get_class_methods($obj) as $method) {
       
$out[] = "メソッド: $method";
   }
   return 
implode("\n"$out);
}


$data = array(M_PI"kludge != cruft");

// 基本オブジェクトを作成する
$fs = new FileStorage($data);
$ws = new WDDXStorage($data);

// オブジェクトの情報を表示する
echo "\$fs オブジェクト\n";
echo 
object_info($fs) . "\n";
echo 
"\n\$ws オブジェクト\n";
echo 
object_info($ws) . "\n";

// 集約を行う

echo "\n\$fs を WDDXStorage クラスに集約します\n";
aggregate($fs"WDDXStorage");
echo 
"\$fs オブジェクト\n";
echo 
object_info($fs) . "\n";

echo 
"\nそれを DBStorage クラスに集約します\n";
aggregate($fs"DBStorage");
echo 
"\$fs オブジェクト\n";
echo 
object_info($fs) . "\n";

echo 
"\nWDDXStorage を集約から解除します\n";
deaggregate($fs"WDDXStorage");
echo 
"\$fs オブジェクト\n";
echo 
object_info($fs) . "\n";

?>

出力内容を見ながら、PHP の集約についての副作用や制限事項を 考えてみましょう。 まず、新しく作成されたオブジェクト $fs および $ws は、期待通りの (対応するクラス定義に もとづく) 結果を出力します。 PHP では実際のところクラス/オブジェクトの要素についてパブリック/ プライベートの区別はありませんが、集約の際には クラス/オブジェクトのプライベート要素はアンダースコア文字 ("_") で始まるとみなします。

$fs オブジェクト
クラス: filestorage
プロパティ: data (array)
    0 => 3.1415926535898
    1 => kludge != cruft
メソッド: filestorage
メソッド: write

$ws オブジェクト
クラス: wddxstorage
プロパティ: data (array)
    0 => 3.1415926535898
    1 => kludge != cruft
プロパティ: version = 1.0
プロパティ: _id = ID::9bb2b640764d4370eb04808af8b076a5
メソッド: wddxstorage
メソッド: store
メソッド: _genid

次に $fsWDDXStorage クラスと集約し、オブジェクトの情報を出力します。 $fs は今でも FileStorage のままですが、プロパティ $version およびメソッド store() が存在することがわかるでしょう。これらは いずれも WDDXStorage で定義されているものです。 注意すべき点は、クラスで定義されているプライベート要素は集約されていない ということです。それらは $ws オブジェクトの中には 存在します。また、WDDXStorage のコンストラクタも 存在しません。これを集約するのは論理的ではありません。

$fs を WDDXStorage クラスに集約します
$fs オブジェクト
クラス: filestorage
プロパティ: data (array)
    0 => 3.1415926535898
    1 => kludge != cruft
プロパティ: version = 1.0
メソッド: filestorage
メソッド: write
メソッド: store

集約処理は、積み重ねていくことが可能です。そこで今度は $fsDBStorage を 集約します。これにより、定義されているすべてのクラスの 保存処理メソッドを使用可能なオブジェクトができあがります。

それを DBStorage クラスに集約します
$fs オブジェクト
クラス: filestorage
プロパティ: data (array)
    0 => 3.1415926535898
    1 => kludge != cruft
プロパティ: version = 1.0
プロパティ: dbtype = mysql
メソッド: filestorage
メソッド: write
メソッド: store
メソッド: save

最後に、プロパティやメソッドを動的に集約したのと同じ方法で、 集約したプロパティやメソッドを解除することも可能です。 $fs から WDDXStorage クラスの集約を解除すると、このような結果になります。

WDDXStorage を集約から解除します
$fs オブジェクト
クラス: filestorage
プロパティ: data (array)
    0 => 3.1415926535898
    1 => kludge != cruft
プロパティ: dbtype = mysql
メソッド: filestorage
メソッド: write
メソッド: save

上で説明しきれなかったことがひとつあります。それは、集約処理の際には 既存のプロパティやメソッドは上書きされないということです。例えば、 FileStorage クラスでは $data というプロパティを定義しており、 WDDXStorage クラスでも同名のプロパティが 定義されていますが、このプロパティが FileStorage のインスタンス化の際に 取得したプロパティの内容を上書きすることはありません。


PHP Manual