リフレクション

PHP5になって、「リバースエンジニアリング(ここでは“スクリプトを解析する行為”を指す)」を行う為の機能、「リフレクション」が搭載されました。

「リフレクション」によって、関数やクラス、メソッド等を解析する事が出来ます。例えば、指定したクラスの構造(継承するクラス名や実装するインターフェイス名、備えるプロパティやメソッド等に関する情報)の出力、指定したインターフェイスを実装するか等のチェック、備えるメソッド名等の取得が行えます。

リフレクタ/「Reflector」インターフェイス/「Reflection」クラス

スクリプトの解析は、関数なら関数用に、クラスならクラス用に定義されたクラス、各種用「リフレクタ」を使用して行います。

「リフレクション」に関係するインターフェイス・クラスは、以下のような継承関係で定義されています。

Exception
      |
      +--- ReflectionException(「リフレクション用例外」)

Reflection(「リフレクション」補助用クラス)

Reflector(「リフレクタ」インターフェイス)
      |
      +--- ReflectionFunction(関数用「リフレクタ」)
      |            |
      |            +--- ReflectionMethod(メソッド用「リフレクタ」)
      |
      +--- ReflectionParameter(関数・メソッドの引数用「リフレクタ」)
      |
      +--- ReflectionClass(クラス・インターフェイス用「リフレクタ」)
      |            |
      |            +--- ReflectionObject(オブジェクト用「リフレクタ」)
      |
      +--- ReflectionProperty(プロパティ用「リフレクタ」)
      |
      +--- ReflectionExtension(拡張モジュール用「リフレクタ」)

上記1つのインターフェイスと9つのクラスが定義されていています。

Reflector」インターフェイスを実装する7つのクラス(「Reflection*」クラス)が「リフレクタ」で、「Reflection」クラスは「リフレクタ」の補助用に定義されるクラス、「ReflectionException」クラスは「リフレクション用例外」(「リフレクタ」が投げる例外)です。

スクリプト(クラスや関数)の解析は各種用「リフレクタ」を使用して行います。あるクラスを解析する場合はクラス用「リフレクタ」を使用し、メソッドを解析する場合はメソッド用「リフレクタ」を使用します。

「リフレクタ」の元となる「Reflector」インターフェイスは下表に記した2つの抽象メソッドを備えます。つまり全ての「リフレクタ」は最低この2つのメソッドを備えます。

「Reflector」インターフェイスが備えるメソッドの機能と返り値の型
メソッド機能返り値の型
abstract static export(void) 各々の情報を出力する。
なお、引数はオーバーライド時に追加されます
void
abstract __toString(void) 文字列として出力しようとした時にコールされる string

各「リフレクタ」は、この2つの他に各々のメソッドを追加で備えます。また、「export()」メソッドは実装時に1~2つの(解析対象の名前を指定する為の)引数が追加されます(各「リフレクタ」が備えるコンストラクタと同じ形態になります)。

「リフレクタ」の補助用に定義される「Reflection」は下表に記した2つのメソッドを備えます。

「Reflection」クラスが備えるメソッドの機能と返り値の型
メソッド機能返り値の型
static export(Reflector リフレクタ) 「リフレクタ」を元に各々の情報を出力する void
static getModifierNames(int 修飾値) 「修飾値」を元に修飾子を格納した配列を返す。
「修飾値」は「getModifiers()」メソッド(「リフレクタ」が備えていれば)によって得られます。
例えば「517」は“「ファイナル」で「プロテクテッド」で「スタティック」”を表し、「array("final", "protected", "static")」を返します
array

「リフレクション」には「リフレクタ」を使用しますが、補助的に「Reflection」クラスが備える2つのクラスメソッドを使用します。

これまた論よりコード。以下のサンプルと結果をご覧下さい。

<pre>
<?php
    #解析対象とする関数を適当に定義する
    function hode_func($arg1, $arg2 = "HODENASU", $arg3 = array("HODE")){
        echo "*** hode_func({$arg1}) ***\n";
    }
    
    #正確な情報を観る為に必要
    ob_start();
    
    #「リフレクタ(関数用)」のクラスメソッド「export()」メソッドを使用
    ReflectionFunction::export("hode_func");
    
    #「リフレクタ(関数用)」オブジェクトを生成する
    $func_reflector = new ReflectionFunction("hode_func");
    
    #「Reflection」クラスのクラスメソッド「export()」メソッドを使用
    Reflection::export($func_reflector);
    
    #「リフレクタ」オブジェクトを文字列として出力する
    echo "* __toString() *\n", $func_reflector, "* __toString() *\n\n";
    
    #「リフレクタ」のプロパティを参照、メソッドを使ってみる
    echo $func_reflector->name, "()'s required parameter number : ",
         $func_reflector->getNumberOfRequiredParameters(), "\n\n";
    
    $func_reflector->invoke("by invoke");
    
    #「リフレクタ」オブジェクトのクローン生成を試みる
    /* clone $func_reflector; */

    #正確な情報を観る為に必要
    echo str_replace(array("<", ">"), array("&lt;", "&gt;"), ob_get_clean());
?>
</pre>
Function [ <user> <visibilty error> function hode_func ] {
  @@ ファイルパス 4 - 6

  - Parameters [3] {
    Parameter #0 [ <required> $arg1 ]
    Parameter #1 [ <optional> $arg2 = 'HODENASU' ]
    Parameter #2 [ <optional> $arg3 = Array ]
  }
}

Function [ <user> <visibilty error> function hode_func ] {
  @@ ファイルパス 4 - 6

  - Parameters [3] {
    Parameter #0 [ <required> $arg1 ]
    Parameter #1 [ <optional> $arg2 = 'HODENASU' ]
    Parameter #2 [ <optional> $arg3 = Array ]
  }
}

* __toString() *
Function [ <user> <visibilty error> function hode_func ] {
  @@ ファイルパス 4 - 6

  - Parameters [3] {
    Parameter #0 [ <required> $arg1 ]
    Parameter #1 [ <optional> $arg2 = 'HODENASU' ]
    Parameter #2 [ <optional> $arg3 = Array ]
  }
}
* __toString() *

hode_func()'s required parameter number : 1

*** hode_func(by invoke) ***

(Fatal error:このオブジェクトのクローンは生成出来ない)

例によって、コメントアウトしている所で「E_ERROR」エラーが発生します。

これが基本的な使い方です。「リフレクタ」及び補助用に定義される「Reflection」クラスが備える「export()」メソッドを使用して各種の情報を出力させます。

なお、「export()」メソッドが出力する内容にはタグで括られた部分があり、そのままだとブラウザで見た時にタグで括られた部分が表示されないので、出力制御関数(「ob_start()」関数と「ob_get_clean()」関数)を使用して対処しています。

「リフレクタ」が備える方の「export()」メソッドを使用する場合は、“解析対象となるもの(クラスや関数等)の名前もしくはオブジェクト”を引数に指定し、「Reflection」クラスが備える方の「export()」メソッドを使用する場合は、“解析対象を指定して生成した「リフレクタ」オブジェクト”を引数に指定します。何れも出力結果は同じです。

見ての通り、“「リフレクタ」が備える方の「export()」メソッドをコールする時に渡す引数”と、「リフレクタ」オブジェクトを生成する時に渡す引数つまり“「リフレクタ」のコンストラクタに渡す引数”は同じです。

今回のサンプルでは、適当に定義した関数を、関数用「リフレクタ」を使用して解析しました。

ReflectionFunction::export("hode_func");」の部分で、適当に定義した関数の名前を引数に「ReflectionFunction」クラス(関数用「リフレクタ」)の「export()」メソッドをコールすると、指定した関数に関する情報が出力されました。

次に、「$func_reflector = new ReflectionFunction("hode_func");」の部分で関数用「リフレクタ」オブジェクトを生成し、「Reflection::export($func_reflector);」の部分で生成した関数用「リフレクタ」オブジェクトを引数に「Reflection」クラス(「リフレクション」補助用クラス)の「export()」メソッドをコールしていますが、結果は「ReflectionFunction::export("hode_func");」の場合と全く同じです。状況に応じて使い分けます。

「リフレクタ」オブジェクトを文字列として出力しようとすると、特殊メソッド「__toString()」メソッドがコールされ、その返り値が出力されました。これまた「export()」メソッドを使用した場合と結果が全く同じです。

「リフレクタ」オブジェクトが備える各種メソッドをコールして、色々な情報を得たり色々出来ます。また、全ての「リフレクタ」は、解析対象の名前が格納された「プロパティ$name」を備えます。更にこのプロパティの値を取得する為の「getName()」メソッドを備えますが、「プロパティ$name」は「パブリック」に宣言されているのでクラス外から直接参照する事も出来ます。

「リフレクタ」オブジェクトのクローンを生成しようとすると、「E_ERROR」エラーを発します。要するに、「リフレクタ」オブジェクトのクローンは生成出来ません。ちなみに、その他の「リフレクタ」の場合も同様にクローンは生成出来ません。ちなみに、各「リフレクタ」は特殊メソッド「__clone()」メソッドを「final private __clone()」で定義しています。これだとクローンを生成しようとした時に可視性を指摘するエラーを発するはずですが、何故か「クローンが生成出来ないオブジェクト」だというエラーを発します。不思議です。

「Reflection」クラスが備えるもう1つのメソッド、「getModifierNames()」メソッドは、クラスやメソッドの定義時に指定された修飾子(「final」や「public」等)を配列に格納して返す関数です。

「リフレクタ」が「getModifiers()」メソッドを備えている場合、このメソッドは、解析対象の例えばクラスの“定義時に指定された修飾子の組み合わせを表す整数値”を返します。このメソッドの返り値を引数に「Reflection::getModifierNames()」メソッドをコールします。

以下のサンプルと結果をご覧下さい。

<pre>
<?php
    #解析対象とするクラス・メソッドを適当に定義する
    class HODE{
        final static public function hode_method(){
            //
        }
    }
    
    #「リフレクタ(メソッド用)」オブジェクトを生成する
    $m_reflector = new ReflectionMethod("HODE", "hode_method");
    
    $name = $m_reflector->class."::".$m_reflector->name."()";
    
    #「getModifiers()」メソッドで修飾子の組み合わせを表す整数値を取得
    $modi_num = $m_reflector->getModifiers();
    
    echo $name."'s modifiers : ", $modi_num, "\n\n", 
         $name."'s modifier_names : ";
    
    #「Reflection::getModifierNames()」メソッドで修飾子を取得
    print_r( Reflection::getModifierNames($modi_num) );
?>
</pre>
HODE::hode_method()'s modifiers : 261

HODE::hode_method()'s modifier_names : Array
(
    [0] => final
    [1] => public
    [2] => static
)

今回のサンプルでは、適当に定義したメソッドを、メソッド用「リフレクタ」を使用して解析しました。

メソッド用「リフレクタ」オブジェクトを生成し、「リフレクタ」が備える「getModifiers()」メソッドで、“解析対象のメソッドが定義時に指定された修飾子の組み合わせを表す整数値”を取得、この値を引数に「Reflection::getModifierNames()」をコールすると、修飾子を格納した配列を得る事が出来ました。

ちなみに、「getModifiers()」メソッドで得られる値は、“「ファイナル」宣言したら「4」加算”、“「アブストラクト」宣言したら「2」加算”、“「プロテクテッド」は「パブリック」に「256」加算”、“「プライベート」は「プロテクテッド」に「512」加算”といった感じの定数です。

と、こんな感じで、解析対象によって各種用「リフレクタ」を使用して解析を行い、補助的に「Reflection」クラスのメソッドを使用します。

リフレクション用例外/「ReflectionException」クラス

「リフレクション用例外」として「ReflectionException」クラスが定義されています。各種「リフレクタ」及び補助用「Reflection」クラスのメソッドは、問題発生時(指定した解析対象が存在しない場合等)にリフレクション用例外オブジェクトを投げます。

以下にサンプルと結果のみ。

<pre>
<?php
    try{
        ReflectionFunction::export("undefined_func");
    }catch(ReflectionException $e){
        echo $e->getMessage(), "\n";
    }
    
    try{
        $func_reflector = new ReflectionFunction("undefined_func");
        Reflection::export($func_reflector);
    }catch(ReflectionException $e){
        echo $e->getMessage();
    }
?>
</pre>
Function undefined_func() does not exist
Function undefined_func() does not exist

docコメント

「リフレクタ」には、スクリプト中の「docコメント」を取得するメソッドを備えるものもあります。この「docコメント」は簡単に言うと“「/**(スラッシュの後に2つのアステリスク)」と「*/」に囲まれたコメント”です。

「関数用リフレクタ」等が備える「getDocComment()」は、所定の位置(「関数用リフレクタ」の場合は、解析対象の関数定義の直前)に記述された「docコメント」を取得する事が出来ます。

以下のサンプルと結果をご覧下さい。

<pre>
<?php
    /**
     * doc comments ? - A -
     */
    /**
     * doc comments ? - B -
     */
    function hode_func(){
        /**
         * doc comments ? - C -
         */
        //
    }
    /**
     * doc comments ? - D -
     */
    
    /*
    * doc comments ? - E -
    */
    
    function nasu_func(){
        //
    }
    
    /**
     * doc comments ? - F -
     */
    class HODE{
        /**
         * doc comments ? - G -
         */
        private function hode_method(){
            //
        }
    }
    
    $reflectors[] = new ReflectionFunction("hode_func");
    $reflectors[] = new ReflectionFunction("nasu_func");
    $reflectors[] = new ReflectionMethod("HODE", "hode_method");
    
    foreach($reflectors as $reflector){
        echo "--- begin ", $reflector->name."()'s doc comments ---\n";
        echo $reflector->getDocComment(), "\n";
        echo "--- end ", $reflector->name."()'s doc comments ---\n\n";
    }
?>
</pre>
--- begin hode_func()'s doc comments ---
/**
     * doc comments ? - B -
     */
--- end hode_func()'s doc comments ---

--- begin nasu_func()'s doc comments ---
/**
     * doc comments ? - D -
     */
--- end nasu_func()'s doc comments ---

--- begin hode_method()'s doc comments ---
/**
         * doc comments ? - G -
         */
--- end hode_method()'s doc comments ---

結果を見ると、通常のコメントは抽出されず、解析対象の定義直前に記述した「docコメント」のみ抽出され、出力されています。

関数用リフレクタ/「ReflectionFunction」クラス

「関数用リフレクタ」として定義される「ReflectionFunction」クラスは下表に記したメソッドを提供します。

「ReflectionFunction」クラスが提供するメソッドの機能
メソッド機能
void __construct(string 関数名) コンストラクタ。
「関数名」を「プロパティ$name」にセットする
bool isInternal(void) ビルトイン関数であるか否かを真偽値で返す
bool isUserDefined(void) ユーザー定義関数であるか否かを真偽値で返す
string getName(void) 解析対象の名前(「プロパティ$name」の値)を返す
string getFileName(void) 定義されているファイル名を返す
int getStartLine(void) 定義開始行番号を返す
int getEndLine(void) 定義終了行番号を返す
string getDocComment(void) 定義直前に記述された「docコメント」を返す。無い場合は「FALSE」を返す
array getStaticVariables(void) 静的変数の名前を添え字に、値を要素にセットした配列を返す
mixed invoke([mixed 引数[, ...]]) 解析対象の関数を(「引数」を渡して)コールする
bool returnsReference(void) リファレンス返しをするか否かを真偽値で返す
array getParameters(void) 各引数を解析対象に「引数用リフレクタ(ReflectionParameter)」オブジェクトを生成し、生成した各「リフレクタ」へのリファレンスを格納した配列を返す
int getNumberOfParameters(void) 引数の数を返す
int getNumberOfRequiredParameters(void) 指定が必須の(デフォルト値がセットされない)引数の数を返す

以下のサンプルと結果をご覧下さい。

<pre>
<?php
    /**
     * sample function
     */
    function hode_func($arg1, $arg2 = "HODENASU", $arg3 = array("HODE")){
        static $var1;
        static $var2 = "HODENASU";
        //static $var3 = array("HODE", "NASU");
    }
    function &nasu_func(){
        //
    }
    
    function func_reflection(ReflectionFunction $reflector){
        $str = "****** ".$reflector->getName()."()'s information ******";
        echo $str, "\n";
        echo $reflector->isInternal() ? "internal" : "user_defined",
                 " function\n",
             "returns", $reflector->returnsReference() ? "" : " not",
                 " reference\n",
             "parameter number : ",
                 $reflector->getNumberOfParameters(), "\n",
             "required parameter number : ",
                 $reflector->getNumberOfRequiredParameters(), "\n",
             "*** parameters ***\n";
        /*
        「getParameters()」メソッドは
        各引数を解析対象とした「引数用リフレクタ」オブジェクトを生成し
        生成した各「リフレクタ」へのリファレンスを格納した配列を返す
        */
        foreach($reflector->getParameters() as $arg_reflector){
            #「引数用リフレクタ」のメソッドを使用する
            echo $arg_reflector->getName(), " : ";
            if($arg_reflector->isOptional())
                print_r($arg_reflector->getDefaultValue());
            else
                echo "not optional";
            echo "\n";
        }
        echo "******************\n";
        echo "static variables : ";
        print_r($reflector->getStaticVariables());
        echo str_pad("", strlen($str), "*"), "\n\n";
    }
    
    #「getStaticVariables()」メソッドで問題が起こる事があるので実行
    //@hode_func();
    
    #正確な情報を観る為に必要
    ob_start();
    
    ReflectionFunction::export("str_pad");     //ビルトイン関数の場合1
    ReflectionFunction::export("str_replace"); //ビルトイン関数の場合2
    ReflectionFunction::export("hode_func");   //ユーザー定義関数の場合
    ReflectionFunction::export("nasu_func");   //ユーザー定義関数の場合
    
    $func_reflector_i1    = new ReflectionFunction("str_pad");
    $func_reflector_i2    = new ReflectionFunction("str_replace");
    $func_reflector_hode  = new ReflectionFunction("hode_func");
    $func_reflector_nasu  = new ReflectionFunction("nasu_func");
    
    func_reflection($func_reflector_i1);
    func_reflection($func_reflector_i2);
    func_reflection($func_reflector_hode);
    func_reflection($func_reflector_nasu);
    
    #正確な情報を観る為に必要
    echo str_replace(array("<", ">"), array("&lt;", "&gt;"), ob_get_clean());
?>
</pre>
Function [ <internal> public function str_pad ] {
}

Function [ <internal> public function str_replace ] {

  - Parameters [4] {
    Parameter #0 [ <required> $param0 ]
    Parameter #1 [ <required> $param1 ]
    Parameter #2 [ <required> $param2 ]
    Parameter #3 [ <required> &$param3 ]
  }
}

/**
     * sample function
     */
Function [ <user> <visibilty error> function hode_func ] {
  @@ ファイルパス 6 - 10

  - Parameters [3] {
    Parameter #0 [ <required> $arg1 ]
    Parameter #1 [ <optional> $arg2 = 'HODENASU' ]
    Parameter #2 [ <optional> $arg3 = Array ]
  }
}

Function [ <user> <visibilty error> function &nasu_func ] {
  @@ ファイルパス 11 - 13
}

****** str_pad()'s information ******
internal function
returns not reference
parameter number : 0
required parameter number : 0
*** parameters ***
******************
static variables : Array
(
)
*************************************

****** str_replace()'s information ******
internal function
returns reference
parameter number : 4
required parameter number : 4
*** parameters ***
 : not optional
 : not optional
 : not optional
 : not optional
******************
static variables : Array
(
)
*****************************************

****** hode_func()'s information ******
user_defined function
returns not reference
parameter number : 3
required parameter number : 1
*** parameters ***
arg1 : not optional
arg2 : HODENASU
arg3 : Array
(
    [0] => HODE
)

******************
static variables : Array
(
    [var1] => 
    [var2] => HODENASU
)
***************************************

****** nasu_func()'s information ******
user_defined function
returns reference
parameter number : 0
required parameter number : 0
*** parameters ***
******************
static variables : Array
(
)
***************************************

結果を見ると、ビルトイン関数を解析した場合に、引数に関する情報が正確に出力されていません。「str_replace()」関数では出力されていますが、「str_pad()」関数では引数があるはずなのに出力されませんでした。

“ビルトイン関数を解析した場合、引数に関する情報が正確に得られるものとそうでないものがある”ようです。

「関数用リフレクタ」が持つ「getParameters()」メソッドは、解析対象の関数が持つ各引数を解析対象に「引数用リフレクタ」オブジェクトを生成し、生成した各オブジェクトへのリファレンスを格納した配列を返します。つまり、このメソッドが返す配列の各要素は「引数用リフレクタ」へのリファレンスなので、その「リフレクタ」が備えるメソッドを使用してそのまま引数を解析する事が出来ます。

getStaticVariables()」メソッドで静的変数を取得しようとした時、静的変数の定義時に配列をセットし、さらにその関数が解析前に一度もコールされていない場合にサーバがダウンしてしまいます。

メソッド用リフレクタ/「ReflectionMethod」クラス

「メソッド用リフレクタ」として定義される「ReflectionMethod」クラスは、「ReflectionFunction」クラスが提供するメソッドに加えて下表に記したメソッドを提供します。

「ReflectionMethod」クラスが提供するメソッドの機能
メソッド機能
void __construct(mixed クラス・インターフェイス名・オブジェクト, string メソッド名) コンストラクタ。
第一引数に「クラス・インターフェイス名」を指定した場合はそれを、「オブジェクト」を指定した場合はそのクラス名を「プロパティ$class」にセットし、「メソッド名」を「プロパティ$name」にセットする
bool isPublic(void) 「パブリック」であるか否かを真偽値で返す
bool isPrivate(void) 「プライベート」であるか否かを真偽値で返す
bool isProtected(void) 「プロテクテッド」であるか否かを真偽値で返す
bool isAbstract(void) 抽象メソッドであるか否かを真偽値で返す
bool isFinal(void) 「ファイナル」であるか否かを真偽値で返す
bool isStatic(void) 「スタティック」であるか否かを真偽値で返す
bool isConstructor(void) コンストラクタであるか否かを真偽値で返す
bool isDestructor(void) デストラクタであるか否かを真偽値で返す
int getModifiers(void) 修飾子の組み合わせを表す整数値(「Reflection::getModifierNames()」メソッドに引数として渡す)を返す
ReflectionClass getDeclaringClass(void) そのメソッドが定義されているクラスを解析対象に生成した「クラス・インターフェイス用リフレクタ(ReflectionClass)」オブジェクトを返す
mixed invoke([mixed 引数[, ...]]) 解析対象のメソッドを(「引数」を渡して)コールする。ただし、コール可能なのは「スタティック」で「パブリック」なメソッドのみ。「パブリック」以外の可視性だと「Trying to invoke protected/private method クラス名::メソッド名 from scope ReflectionMethod」というメッセージ、「スタティック」でないと「Non-object passed to Invoke()」というメッセージ、また抽象メソッドだと「Trying to invoke abstract method クラス名::メソッド名」というメッセージと共に「リフレクション用例外」を投げる

以下のサンプルと結果をご覧下さい。

<pre>
<?php
    class HODE{
        /**
         * sample method
         */
        final static public function hode_method($arg = "HODENASU"){
            //
        }
    }
    
    class GASU extends HODE{
        //
    }
    
    #正確な情報を観る為に必要
    ob_start();
    
    ReflectionMethod::export("GASU", "hode_method");
    ReflectionMethod::export(new GASU, "hode_method");
    
    $r = new ReflectionMethod("GASU", "hode_method");
    
    $str = "****** {$r->class}::{$r->name}()'s information ******";
    echo $str, "\n";
    
    echo "Declaring : ",
         $r->getDeclaringClass()->getName()."::".$r->getName()."()\n";
    
    echo "is ", $r->isConstructor() ? "" : "not ", "constructor\n";
    echo "is ", $r->isFinal() ? "" : "not ", "final\n";
    echo "is ", $r->isStatic() ? "" : "not ", "static\n";
    
    echo str_pad("", strlen($str), "*"), "\n\n";
    
    #正確な情報を観る為に必要
    echo str_replace(array("<", ">"), array("&lt;", "&gt;"), ob_get_clean());
?>
</pre>
/**
         * sample method
         */
Method [ <user> final static public method hode_method ] {
  @@ ファイルパス 7 - 9

  - Parameters [1] {
    Parameter #0 [ <optional> $arg = 'HODENASU' ]
  }
}

/**
         * sample method
         */
Method [ <user> final static public method hode_method ] {
  @@ ファイルパス 7 - 9

  - Parameters [1] {
    Parameter #0 [ <optional> $arg = 'HODENASU' ]
  }
}

****** GASU::hode_method()'s information ******
Declaring : HODE::hode_method()
is not constructor
is final
is static
***********************************************

解析対象の指定は、第一引数にクラス名もしくはオブジェクトを、第二引数にメソッド名を指定します。オブジェクトを指定した場合はそのクラス名が解析対象となり、結局クラス名を指定した場合と同じです。

「メソッド用リフレクタ」は「関数用リフレクタ」を継承しているので、「関数用リフレクタ」が提供するメソッドも使用出来ます。

(関数・メソッドの)引数用リフレクタ/「ReflectionParameter」クラス

「(関数・メソッドの)引数用リフレクタ」として定義される「ReflectionParameter」クラスは下表に記したメソッドを提供します。

「ReflectionParameter」クラスが提供するメソッドの機能
メソッド機能
void __construct(string 関数名, string 引数名) コンストラクタ。
「引数名」を「プロパティ$name」にセットする
string getName(void) 解析対象の名前(「プロパティ$name」の値)を返す
bool isPassedByReference(void) リファレンスを受け取る引数であるか否かを真偽値で返す
ReflectionClass getClass(void) 引数にクラス名を指定している場合に、そのクラスを解析対象に生成した「クラス・インターフェイス用リフレクタ(ReflectionClass)」オブジェクトを返す。指定されていない場合は「NULL」を返す
bool allowsNull(void) 引数に「NULL」が渡される事を許可するか(クラス名が指定された引数には必ず指定したクラスのオブジェクトを渡さなければならず、それ以外の値を渡すと「E_ERROR」エラーを発する。つまり「NULL」を許可しない)否かを真偽値で返す
bool isOptional(void) 省略可能である(デフォルト値が設定されている)か否かを真偽値で返す
bool isDefaultValueAvailable(void) デフォルト値が設定されているか否かを真偽値で返す
mixed getDefaultValue(void) 引数に設定されたデフォルト値を返す。デフォルト値が設定されていないと「Parameter is not optional」というメッセージと共に「リフレクション用例外」を投げる

以下のサンプルと結果をご覧下さい。

<pre>
<?php
    function hode_func(HODE $arg1, &$arg2 = array("HODE")){
        //
    }
    
    class HODE{
        public function hode_method(GASU $arg1, &$arg2 = "HODE",
                                                $arg3 = array("HODE")){
            //
        }
    }
    
    class GASU{
        //
    }
    
    #正確な情報を観る為に必要
    ob_start();
    
    ReflectionParameter::export("hode_func", "arg1");
    ReflectionParameter::export("hode_func", "arg2");
    
    echo "\n";
    
    #メソッドの引数の解析は「メソッド用リフレクタ」経由で行う
    $method_r = new ReflectionMethod("HODE", "hode_method");
    
    /*
    「関数/メソッド用リフレクタが提供する」「getParameters()」メソッドは
    各引数を解析対象とした「引数用リフレクタ」オブジェクトを生成し
    生成した各「リフレクタ」へのリファレンスを格納した配列を返す
    */
    foreach($method_r->getParameters() as $r){
        #「$r」が「引数用リフレクタ」
        $str = "****** {$method_r->class}::{$method_r->name}() - $".
               $r->getName()."'s information ******";
        echo $str, "\n";
        
        if($r->isOptional()){
            echo "is optional, default value : ";
            var_dump($r->getDefaultValue());
        }else
            echo "is not optional\n";
        
        if($r->allowsNull())
            echo "is allows NULL\n";
        else{
            echo "is not allows NULL, must be an instance of ",
                 $r->getClass()->getName(), "\n";
        }
        
        echo "is ", $r->isPassedByReference() ? "" : "not ",
             "passed by reference\n";
        
        echo str_pad("", strlen($str), "*"), "\n\n";
    }
    
    #正確な情報を観る為に必要
    echo str_replace(array("<", ">"), array("&lt;", "&gt;"), ob_get_clean());
?>
</pre>
Parameter #0 [ <required> HODE $arg1 ]
Parameter #1 [ <optional> &$arg2 = Array ]

****** HODE::hode_method() - $arg1's information ******
is not optional
is not allows NULL, must be an instance of GASU
is not passed by reference
*******************************************************

****** HODE::hode_method() - $arg2's information ******
is optional, default value : string(4) "HODE"
is allows NULL
is passed by reference
*******************************************************

****** HODE::hode_method() - $arg3's information ******
is optional, default value : array(1) {
  [0]=>
  string(4) "HODE"
}
is allows NULL
is not passed by reference
*******************************************************

関数の引数を解析する場合は関数名と引数名を指定して個別に解析する事が出来ますが、メソッドの引数は指定出来ず、個別の解析が出来ません。メソッドの引数を解析する場合は、まず「メソッド用リフレクタ」を生成し、「関数用/メソッド用リフレクタ」が提供する「getParameters()」メソッドが生成する「引数用リフレクタ」を使用します。どっち道、引数の解析を個別に解析するよりもまとめて解析する方が自然だと思うので、関数の場合もメソッドの場合も「関数用/メソッド用リフレクタ」の「getParameters()」メソッド経由で解析を行います。

クラス・インターフェイス用リフレクタ/「ReflectionClass」クラス

「クラス・インターフェイス用リフレクタ」として定義される「ReflectionClass」クラスは下表に記したメソッドを提供します。

「ReflectionClass」クラスが提供するメソッドの機能
メソッド機能
void __construct(string クラス・インターフェイス名) コンストラクタ。
「クラス・インターフェイス名」を「プロパティ$name」にセットする
string getName(void) 解析対象の名前(「プロパティ$name」の値)を返す
bool isInternal(void) ビルトインクラス・インターフェイスであるか否かを真偽値で返す
bool isUserDefined(void) ユーザー定義クラス・インターフェイスであるか否かを真偽値で返す
bool isInstantiable(void) インスタンスを生成できるか否かを真偽値で返す・・・のかと思いきや、クラスであるか否かを真偽値で返す(抽象クラスの場合でも「TRUE」を返す」)。インターフェイスだと「FALSE」を返す
string getFileName(void) 定義されているファイル名を返す
int getStartLine(void) 定義開始行番号を返す
int getEndLine(void) 定義終了行番号を返す
string getDocComment(void) 定義直前に記述された「docコメント」を返す。無い場合は「FALSE」を返す
ReflectionMethod getConstructor(void) コンストラクタを解析対象に生成した「メソッド用リフレクタ(ReflectionMethod)」オブジェクトを返す。コンストラクタが存在しない場合は「NULL」を返す
ReflectionMethod getMethod(string メソッド名) 指定した「メソッド名」を解析対象に生成した「メソッド用リフレクタ(ReflectionMethod)」オブジェクトを返す。指定したメソッドが未定義だと「Method メソッド名 does not exist」というメッセージと共に「リフレクション用例外」を投げる
array getMethods(void) 備える全てのメソッドを解析対象に「メソッド用リフレクタ(ReflectionMethod)」オブジェクトを生成し、生成した各「リフレクタ」へのリファレンスを格納した配列を返す
ReflectionParameter getProperty(string プロパティ名) 指定した「プロパティ名」を解析対象に生成した「プロパティ用リフレクタ(ReflectionProperty)」オブジェクトを返す。指定したプロパティが未定義だと「Property プロパティ名 does not exist」というメッセージと共に「リフレクション用例外」を投げる
array getProperties(void) 備える全てのプロパティを解析対象に「プロパティ用リフレクタ(ReflectionProperty)」オブジェクトを生成し、生成した各「リフレクタ」へのリファレンスを格納した配列を返す
array getConstants(void) クラス定数の名前を添え字に、値を要素にセットした配列を返す
mixed getConstant(string 定数名) 指定した「定数名」の値を返す。未定義の場合は「FALSE」を返す
array getInterfaces(void) 実装する全てのインターフェイスを解析対象に「クラス・インターフェイス用リフレクタ(ReflectionClass)」オブジェクトを生成し、生成した各「リフレクタ」へのリファレンスを格納した配列を返す
bool isInterface(void) インターフェイスであるか否かを真偽値で返す
bool isAbstract(void) 抽象クラスであるか否かを真偽値で返す
bool isFinal(void) 「ファイナル」であるか否かを真偽値で返す
int getModifiers(void) 修飾子の組み合わせを表す整数値(「Reflection::getModifierNames()」メソッドに引数として渡す)を返す
bool isInstance(object オブジェクト) 指定した「オブジェクト」がこのクラスのインスタンスであるか否かを真偽値で返す。派生クラスのインスタンスの場合は「FALSE」を返す
object newInstance(void) インスタンスを生成して返す。インスタンスの生成が出来ない場合は「E_ERROR」エラーを発する
ReflectionClass getParentClass(void) 基底クラスを解析対象に生成した「クラス・インターフェイス用リフレクタ(ReflectionClass)」オブジェクトを返す。基底クラスが存在しない場合は「FALSE」を返す
bool isSubclassOf(string クラス・インターフェイス名) 指定した「クラス・インターフェイス名」を継承・実装しているか否かを真偽値で返す
array getStaticProperties(void) クラスプロパティの名前を添え字に、値を要素にセットした配列を返す。
返される配列の添え字には、「パブリック」ならそのまま、「プロテクテッド」なら接頭辞「*(アステリスク)」を付けたプロパティ名が、「プライベート」なら接頭辞として“定義しているクラス名”を付けたプロパティ名がセットされる。
また、解析対象のクラスで定義された「パブリック」なプロパティの場合のみその値が、それ以外(基底クラスで定義されたか、もしくは「パブリック」以外の可視性)の場合はリファレンスが配列に格納されます
array getDefaultProperties(void) プロパティの名前を添え字に、値を要素にセットした配列を返す。
ただし、クラス内からアクセス出来ないプロパティ(基底クラスで定義された「プライベート」なプロパティ)はセットされない
bool isIterateable(void) イテレータであるか(「Iterator」インターフェイスもしくは「IteratorAggregate」インターフェイスを実装しているか)否かを真偽値で返す
bool implementsInterface(string インターフェイス名) 指定した「インターフェイス名」を実装しているか否かを真偽値で返す
ReflectionExtension getExtension(void) 拡張モジュールで定義されている場合に、その拡張モジュールを解析対象に生成した「拡張モジュール用リフレクタ(ReflectionExtension)」オブジェクトを返す。ユーザー定義の場合は「NULL」を返す
string getExtensionName(void) 拡張モジュールで定義されている場合はその拡張モジュール名を、ユーザー定義である場合は「FALSE」を返す

以下のサンプルと結果をご覧下さい。

<pre>
<?php
    /**
     * sample interface
     */
    interface iHODE{
        const HODE_CONST = "HODENASU";
        /**
         * sample method
         */
        function hode_method($arg);
    }
    
    class NDA{
        //
    }
    
    /**
     * sample class
     */
    class HODE extends NDA implements iHODE{
        /**
         * sample property
         */
        private $pri_var        = "private_property";
        static private $sta_var = "static_property";
        /**
         * sample method
         */
        public function hode_method($arg){
            //
        }
    }
    
    class NASU extends HODE{
        //
    }
    
    #正確な情報を観る為に必要
    ob_start();
    
    ReflectionClass::export("Exception"); //ビルトインクラス
    ReflectionClass::export("iHODE");     //ユーザー定義インターフェイス
    ReflectionClass::export("HODE");      //ユーザー定義クラス
    
    $r = new ReflectionClass("HODE");
    
    $str = "****** ".($r->isInterface() ? "interface " : "class ").
           $r->getName()."'s information ******";
    echo $str, "\n";
    
    echo "constants : ";
    print_r($r->getConstants());
    
    echo "is ", $r->isSubclassOf("NDA") ? "" : "not ",
         "sub class of 'NDA'\n";
    
    echo "is ", $r->isIterateable() ? "" : "not ", "iterateable\n";
    
    echo "is ", $r->implementsInterface("iHODE") ? "" : "not ",
         "implements interface 'iHODE'\n";
    
    echo "'new HODE' is ", $r->isInstance(new HODE) ? "" : "not ",
         "instance of ", $r->getName(), "\n";
    
    echo "'new NASU' is ", $r->isInstance(new NASU) ? "" : "not ",
         "instance of ", $r->getName(), "\n";
    
    echo str_pad("", strlen($str), "*"), "\n\n";
    
    #正確な情報を観る為に必要
    echo str_replace(array("<", ">"), array("&lt;", "&gt;"), ob_get_clean());
?>
</pre>
Class [ <internal> class Exception ] {

  - Constants [0] {
  }

  - Static properties [0] {
  }

  - Static methods [0] {
  }

  - Properties [6] {
    Property [ <default> protected $message ]
    …省略
    Property [ <default> private $trace ]
  }

  - Methods [9] {
    Method [ <internal> final private method __clone ] {
    }
    
    …省略
    
    Method [ <internal> public method __toString ] {
    }
  }
}

/**
     * sample interface
     */
Interface [ <user> interface iHODE ] {
  @@ ファイルパス 6-12

  - Constants [1] {
    Constant [ string HODE_CONST ] { }
  }

  - Static properties [0] {
  }

  - Static methods [0] {
  }

  - Properties [0] {
  }

  - Methods [1] {
    /**
         * sample method
         */
    Method [ <user> abstract public method hode_method ] {
      @@ ファイルパス 11 - 11

      - Parameters [1] {
        Parameter #0 [ <required> $arg ]
      }
    }
  }
}

/**
     * sample class
     */
Class [ <user> class HODE extends NDA implements iHODE ] {
  @@ ファイルパス 21-33

  - Constants [1] {
    Constant [ string HODE_CONST ] { }
  }

  - Static properties [1] {
    Property [ private static $sta_var ]
  }

  - Static methods [0] {
  }

  - Properties [1] {
    Property [ <default> private $pri_var ]
  }

  - Methods [1] {
    /**
         * sample method
         */
    Method [ <user> public method hode_method ] {
      @@ ファイルパス 30 - 32

      - Parameters [1] {
        Parameter #0 [ <required> $arg ]
      }
    }
  }
}

****** class HODE's information ******
constants : Array
(
    [HODE_CONST] => HODENASU
)
is sub class of 'NDA'
is not iterateable
is implements interface 'iHODE'
'new HODE' is instance of HODE
'new NASU' is not instance of HODE
**************************************

「クラス・インターフェイス用リフレクタ」で、インターフェイスとクラスの解析が行えます。「クラス・インターフェイス用リフレクタ」は、クラス・インターフェイスが備えるプロパティやメソッド、クラスが実装するインターフェイス等を解析対象に各種用リフレクタを生成するメソッド等を提供するので、それを利用してプロパティ等の解析を行えます。

オブジェクト用リフレクタ/「ReflectionObject」クラス

「オブジェクト用リフレクタ」として定義される「ReflectionObject」クラスは、「ReflectionClass」クラスが提供するメソッドに加えて下表に記したメソッドを提供します。

「ReflectionObject」クラスが提供するメソッドの機能
メソッド機能
void __construct(object オブジェクト) コンストラクタ。
「オブジェクト」のクラス名を「プロパティ$name」にセットする

以下のサンプルと結果をご覧下さい。

<pre>
<?php
    $xml = <<< XML
<?xml version="1.0"?>
<hode></hode>

XML;
?>
<?php
    /**
     * sample class
     */
    class HODE{
        private $var;
        public function __construct(){
            $this->var         = "HODENASU";
            $this->dynamic_var = "Dynamic HODENASU";
        }
    }
    
    $xml_iterator = new SimpleXMLIterator($xml);
    
    #正確な情報を観る為に必要
    ob_start();
    
    ReflectionClass::export("HODE");
    
    ReflectionObject::export(new HODE);
    ReflectionObject::export($xml_iterator);
    
    $r = new ReflectionObject($xml_iterator);
    
    $str = "****** object of ".$r->getName()."'s information ******";
    echo $str, "\n";
    
    echo "is ", $r->getExtensionName() ?
                $r->getExtension()->getName() : "not", " extension\n";
    
    echo "is ", $r->isIterateable() ? "" : "not ", "iterateable\n";
    
    echo str_pad("", strlen($str), "*"), "\n\n";
    
    #正確な情報を観る為に必要
    echo str_replace(array("<", ">"), array("&lt;", "&gt;"), ob_get_clean());
?>
</pre>
/**
     * sample class
     */
Class [ <user> class HODE ] {
  @@ ファイルパス 13-19

  - Constants [0] {
  }

  - Static properties [0] {
  }

  - Static methods [0] {
  }

  - Properties [1] {
    Property [ <default> private $var ]
  }

  - Methods [1] {
    Method [ <user> <ctor> public method __construct ] {
      @@ ファイルパス 15 - 18
    }
  }
}

/**
     * sample class
     */
Object of class [ <user> class HODE ] {
  @@ ファイルパス 13-19

  - Constants [0] {
  }

  - Static properties [0] {
  }

  - Static methods [0] {
  }

  - Properties [1] {
    Property [ <default> private $var ]
  }

  - Dynamic properties [1] {
    Property [ <dynamic> public $dynamic_var ]
  }

  - Methods [1] {
    Method [ <user> <ctor> public method __construct ] {
      @@ ファイルパス 15 - 18
    }
  }
}

Object of class [ <internal:SimpleXML> <iterateable> 
                    class SimpleXMLIterator extends SimpleXMLElement 
                      implements Traversable, RecursiveIterator, 
                                                           Iterator ] {

  - Constants [0] {
  }

  - Static properties [0] {
  }

  - Static methods [0] {
  }

  - Properties [0] {
  }

  - Dynamic properties [0] {
  }

  - Methods [12] {
    Method [ <internal> public method rewind ] {
    }

    …省略

    Method [ <internal> public method children ] {
    }
  }
}

****** object of class SimpleXMLIterator's information ******
is SimpleXML extension
is iterateable
*************************************************************

「オブジェクト用リフレクタ」は解析対象にオブジェクトを指定する事以外「クラス・インターフェイス用リフレクタ」と殆ど同じです。結果を見ると、「Dynamic properties」なる項目が追加されています。これは、オブジェクト生成後に動的に生成されたプロパティ(クラス定義の時点で定義されたプロパティではなく)です。

プロパティ用リフレクタ/「ReflectionProperty」クラス

「プロパティ用リフレクタ」として定義される「ReflectionProperty」クラスは下表に記したメソッドを提供します。

「ReflectionProperty」クラスが提供するメソッドの機能
メソッド機能
void __construct(mixed クラス名・オブジェクト, string プロパティ名) コンストラクタ。
第一引数に「クラス名」を指定した場合はそれを、「オブジェクト」を指定した場合は指定した「プロパティ名」が定義されているクラスの名前を「プロパティ$class」にセットし、「プロパティ名」を「プロパティ$name」にセットする。
指定した「プロパティ名」が「パブリック」以外の可視性である場合は「プロパティ$name」がセットされません
string getName(void) 解析対象の名前(「プロパティ$name」の値)を返す
mixed getValue(object オブジェクト) 指定した「オブジェクト」が解析対象と同じ名前のプロパティを備えている場合に、その「オブジェクト」が備えるプロパティの値を返す。「パブリック」以外の可視性である場合やプロパティが存在しない場合は「E_ERROR」エラーを発する
void setValue(object オブジェクト, mixed 値) 指定した「オブジェクト」が解析対象と同じ名前のプロパティを備えている場合に、その「オブジェクト」が備えるプロパティに指定した「値」をセットする。「パブリック」以外の可視性である場合やプロパティが存在しない場合は「E_ERROR」エラーを発する
bool isPublic(void) 「パブリック」であるか否かを真偽値で返す
bool isPrivate(void) 「プライベート」であるか否かを真偽値で返す
bool isProtected(void) 「プロテクテッド」であるか否かを真偽値で返す
bool isStatic(void) 「スタティック」であるか否かを真偽値で返す
bool isDefault(void) 不明(常に「TRUE」を返す)
int getModifiers(void) 修飾子の組み合わせを表す整数値(「Reflection::getModifierNames()」メソッドに引数として渡す)を返す
ReflectionClass getDeclaringClass(void) プロパティが定義されているクラスを解析対象に生成した「クラス・インターフェイス用リフレクタ(ReflectionClass)」オブジェクトを返す

以下のサンプルと結果をご覧下さい。

<pre>
<?php
    class HODE{
        public    $pub_var = "public_property";
        protected $pro_var = "protected_property";
        private   $pri_var = "private_property";
        private function pri_method(){
            //
        }
    }
    
    class GASU extends HODE{
        //
    }
    
    #正確な情報を観る為に必要
    ob_start();
    
    try{
        #「GASU」クラスからアクセス不可な「pri_method()」を解析
        ReflectionMethod::export("GASU", "pri_method");
        
        #「GASU」クラスからアクセス不可な「$pri_var」を解析
        ReflectionProperty::export("GASU", "pri_var");
        
    }catch(ReflectionException $e){
        echo "* ReflectionException *\n",
             $e->getMessage(), "\n* ReflectionException *\n\n";
    }
    
    ReflectionProperty::export("GASU", "pro_var");
    ReflectionProperty::export(new GASU, "pro_var");
    
    #“「パブリック」でないメソッド”の「メソッド用リフレクタ」
    $r = new ReflectionMethod("GASU", "pri_method");
    var_dump($r->class, $r->name, $r->getName(), $r->isPrivate());
    
    #“「パブリック」でないプロパティ”の「プロパティ用リフレクタ」
    $r = new ReflectionProperty("GASU", "pro_var");
    var_dump($r->class, $r->name, $r->getName(), $r->isProtected());
    
    #“「パブリック」なプロパティ”の「プロパティ用リフレクタ」
    $r = new ReflectionProperty("GASU", "pub_var");
    var_dump($r->class, $r->name, $r->getName(), $r->isPublic());
    
    $str = "\n****** {$r->class}::\${$r->name}'s information ******";
    echo $str, "\n";
    
    echo "Declaring : ",
         $r->getDeclaringClass()->getName()."::$".$r->getName()."\n";
    
    echo "is ", $r->isStatic() ? "" : "not ", "static\n";
    echo "is ", $r->isDefault() ? "" : "not ", "default\n";
    
    $obj = $r->getDeclaringClass()->newInstance();
    
    echo "old value : ", $r->getValue($obj), "\n";
    $r->setValue($obj, "HODENASU!!!");
    echo "new value : ", $r->getValue($obj), "\n";
    
    echo str_pad("", strlen($str), "*"), "\n\n";
    
    #正確な情報を観る為に必要
    echo str_replace(array("<", ">"), array("&lt;", "&gt;"), ob_get_clean());
?>
</pre>
Method [ <user> private method pri_method ] {
  @@ ファイルパス 7 - 9
}

* ReflectionException *
Property GASU::$pri_var does not exist
* ReflectionException *

Property [ <default> protected $pro_var ]

Property [ <default> protected $pro_var ]

string(4) "GASU"
string(10) "pri_method"
string(10) "pri_method"
bool(true)
string(4) "HODE"
string(0) ""
string(0) ""
bool(true)
string(4) "HODE"
string(7) "pub_var"
string(7) "pub_var"
bool(true)

****** HODE::$pub_var's information ******
Declaring : HODE::$pub_var
is not static
is default
old value : public_property
new value : HODENASU!!!
*******************************************

「メソッド用リフレクタ」ではアクセス不可なメソッドも解析出来ましたが、「プロパティ用リフレクタ」では出来ず「未定義だ」という例外を投げます。また、アクセス可能なプロパティでも、「パブリック」以外の可視性に宣言されたプロパティの名前は「リフレクタ」オブジェクトの「プロパティ$name」にセットされません。が、解析は出来ます。

結果を見ると、「リフレクタ」オブジェクトの「プロパティ$class」には、「リフレクタ」オブジェクトの生成時に指定したクラスの名前ではなく、解析対象が定義されているクラスの名前がセットされています(「メソッド用リフレクタ」では指定したクラスの名前がセットされます)。

getValue()」メソッドと「setValue()」メソッドは、コール時の引数にオブジェクトを渡します。渡したオブジェクトが解析対象と同じ名前のプロパティを備えている場合に、その「オブジェクト」が備えるプロパティの値を取得/セットします。「パブリック」以外の可視性である場合やプロパティが存在しない場合には「E_ERROR」エラーを発します。

拡張モジュール用リフレクタ/「ReflectionExtension」クラス

「拡張モジュール用リフレクタ」として定義される「ReflectionExtension」クラスは下表に記したメソッドを提供します。

「ReflectionExtension」クラスが提供するメソッドの機能
メソッド機能
void __construct(string 拡張モジュール名) コンストラクタ。
「拡張モジュール名」を「プロパティ$name」にセットする
string getName(void) 解析対象の名前(「プロパティ$name」の値)を返す
string getVersion(void) モジュールのバージョン情報があれば返します。無い場合は「NULL」を返します
array getFunctions(void) 定義する全ての関数を解析対象に「関数用リフレクタ(ReflectionFunction)」オブジェクトを生成し、生成した各「リフレクタ」へのリファレンスを格納した配列を返す
array getConstants(void) 定数の名前を添え字に、値を要素にセットした配列を返す
array getINIEntries(void) ディレクティブの名前を添え字に、値(Local Value)を要素にセットした配列を返す
array getClasses(void) 定義する全てのクラス・インターフェイスを解析対象に「クラス・インターフェイス用リフレクタ(ReflectionClass)」オブジェクトを生成し、生成した各「リフレクタ」へのリファレンスを格納した配列を返す
array getClassNames(void) 定義する全てのクラス・インターフェイスの名前を格納した配列を返す

以下のサンプルと結果をご覧下さい。

<pre>
<?php
    #正確な情報を観る為に必要
    ob_start();
    
    ReflectionExtension::export("standard");
    
    $ext_arr = array();
    $func_num = $class_num = 0;
    
    foreach(get_loaded_extensions() as $name){
        $r = new ReflectionExtension($name);
        
        $arr["version"]     = $r->getVersion();
        $arr["INI_entries"] = $r->getINIEntries();
        $arr["constants"]   = $r->getConstants();
        $arr["functions"]   = array();
        foreach($r->getFunctions() as $func_r){
            array_push($arr["functions"], $func_r->getName());
            $func_num++;
        }
        $arr["classes"] = array();
        foreach($r->getClasses() as $class_r){
            array_push($arr["classes"], $class_r->getName());
            $class_num++;
        }
        $arr["class_names"] = $r->getClassNames();
        
        $ext_arr[$r->getName()] = $arr;
    }
    
    echo "function number : ", $func_num, "\n",
         "interface and class number : ", $class_num, "\n\n";
    
    print_r($ext_arr);
    
    #正確な情報を観る為に必要
    echo str_replace(array("<", ">"), array("&lt;", "&gt;"), ob_get_clean());
    
    echo "\nmbstring.http_output : ",
         ini_set("mbstring.http_output", "SJIS"), "\n";
    
    $r1 = new ReflectionExtension("mbstring");
    
    mb_http_output("UTF-8");
    
    $r2 = new ReflectionExtension("mbstring");
    
    $ini_arr[] = $r1->getINIEntries();
    $ini_arr[] = $r2->getINIEntries();
    
    echo "mbstring.http_output : ", $ini_arr[0]["mbstring.http_output"],
         "\n",
         "mbstring.http_output : ", $ini_arr[1]["mbstring.http_output"];
?>
</pre>
Extension [ <persistent> extension #12 standard version 5.0.3 ] {

 - INI {
    Entry [ safe_mode_protected_env_vars <ALL> ]
      Current = 'LD_LIBRARY_PATH'
    }
    …省略
    Entry [ url_rewriter.tags <ALL> ]
      Current = 'a=href,area=href,frame=src,input=src,form=fakeentry'
    }
  }

 - Functions {
    Function [ <internal> public function constant ] {
    }
    …省略
    Function [ <internal> public function date_sunset ] {
    }
  }

 - Classes [2] {

    Class [ <internal:standard> class php_user_filter ] {

      - Constants [0] {
      }

      - Static properties [0] {
      }

      - Static methods [0] {
      }

      - Properties [0] {
      }

      - Methods [3] {
        Method [ <internal> public method filter ] {
        }

        Method [ <internal> public method onCreate ] {
        }

        Method [ <internal> public method onClose ] {
        }
      }
    }

    Class [ <internal:standard> class Directory ] {

      - Constants [0] {
      }

      - Static properties [0] {
      }

      - Static methods [0] {
      }

      - Properties [0] {
      }

      - Methods [3] {
        Method [ <internal> public method close ] {
        }

        Method [ <internal> public method rewind ] {
        }

        Method [ <internal> public method read ] {
        }
      }
    }
  }
}

function number : 1100
interface and class number : 61

Array
(
    [bcmath] => Array
        (
            [version] => 
            [INI_entries] => Array
                (
                    [bcmath.scale] => 0
                )

            [constants] => Array
                (
                )

            [functions] => Array
                (
                    [0] => bcadd
                    …省略
                    [9] => bcpowmod
                )

            [classes] => Array
                (
                )

            [class_names] => Array
                (
                )

        )

    …省略
    
    [SPL] => Array
        (
            [version] => 0.2
            [INI_entries] => Array
                (
                )

            [constants] => Array
                (
                    [RIT_LEAVES_ONLY] => 0
                    [RIT_SELF_FIRST] => 1
                    [RIT_CHILD_FIRST] => 2
                    [CIT_CALL_TOSTRING] => 1
                    [CIT_CATCH_GET_CHILD] => 2
                )

            [functions] => Array
                (
                    [0] => spl_classes
                    [1] => class_parents
                    [2] => class_implements
                )

            [classes] => Array
                (
                    [0] => RecursiveIterator
                    …省略
                    [11] => RecursiveDirectoryIterator
                )

            [class_names] => Array
                (
                    [0] => RecursiveIterator
                    …省略
                    [11] => RecursiveDirectoryIterator
                )

        )

    …省略
    
    [standard] => Array
        (
            [version] => 5.0.3
            [INI_entries] => Array
                (
                    [safe_mode_protected_env_vars] => LD_LIBRARY_PATH
                    …省略
                    [url_rewriter.tags] => a=href,area=href,frame=src,
                                               input=src,form=fakeentry
                )

            [constants] => Array
                (
                    [CONNECTION_ABORTED] => 1
                    …省略
                    [IMAGETYPE_XBM] => 16
                )

            [functions] => Array
                (
                    [0] => constant
                    …省略
                    [475] => date_sunset
                )

            [classes] => Array
                (
                    [0] => php_user_filter
                    [1] => Directory
                )

            [class_names] => Array
                (
                    [0] => php_user_filter
                    [1] => Directory
                )

        )

    …省略

)

mbstring.http_output : pass
mbstring.http_output : SJIS
mbstring.http_output : SJIS

「拡張モジュール用リフレクタ」ではインストールされて有効な拡張モジュールを解析して、定義されたクラスや関数等を調べる事が出来ます。

作成日:2005年02月13日 最終更新日:2005年02月13日
【印刷モード風モード で表示】