基底クラス PEARのデストラクタ[Pear]

メモ:  Category:pear

Pear の基底クラスである PEARクラス を読んでみます。

まず目に付くのがコンストラクタです。PHP4では、デストラクタがサポートされていません そのため、PEARのコンストラクタでは、スクリプト処理が完了した際に実行される 関数を 登録する register_shutdown_function を使ってデストラクタっぽく振舞うようにしています。

//PEARのコンストラクタ
while ($classname && strcasecmp($classname, "pear")) {
    $destructor = "_$classname";
    if (method_exists($this, $destructor)) {
        global $_PEAR_destructor_object_list;
        $_PEAR_destructor_object_list[] = &$this;
        if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) {
            register_shutdown_function("_PEAR_call_destructors");
            $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true;
        }
        break;
    } else {
        $classname = get_parent_class($classname);
    }
}

このソースから、デストラクタとして登録するには_(アンダースコア)+クラス名がデストラクタ になるようです。

method_exists関数によって対象となるクラスにデストラクタとして使用する関数が存在するか 確認しています。その後、対象となるクラスを$_PEAR_destructor_object_list[]に登録しています。

次にPEARのコンストラクタで登録されたregister_shutdown_function("_PEAR_call_destructors"); _PEAR_call_destructors関数を見てみます。

//PEARデストラクタ
while (list($k, $objref) = each($_PEAR_destructor_object_list)) {
    $classname = get_class($objref);
    while ($classname) {
        $destructor = "_$classname";
        if (method_exists($objref, $destructor)) {
            $objref->$destructor();
            break;
        } else {
            $classname = get_parent_class($classname);
        }
    }
}

$_PEAR_destructor_object_listからオブジェクトを取得し、デストラクタとして登録された 関数を実行しています。

注意しないといけないのは、register_shutdown_functionは

  • スクリプト処理が完了した際に実行される
  • ラウザへの出力は許可されない。 そのためprintまたはechoを使用してデバッグを行うことができない。

bluenote by BBB