@blog.justoneplanet.info

日々勉強

PHP Reflection API

PHP5には完全なリフレクションAPIが付属していて、クラス、インターフェイス、関数、メソッドなどについて、リバースエンジニアリングを行うことができる。

■定義済みクラスについて調べる

定義済みクラスについて調べるには、以下のようにReflectionClassクラスを使う。

<?php
/**
 * Dog
 */
class Dog {
    private $name;
    public function __construct($name){
        $this->name = $name;
    }
    /**
     * bark
     * @param
     * @return
     */
    public function bark(){
        print('Bow!');
    }
}
$class = new ReflectionClass('Dog');
print($class->getName());//Dog
print($class->getDocComment());
/**
 * Dog
 */
print($class->getFileName());
print($class->getStartLine());

$methods = $class->getMethods();
var_dump($methods);
/*
array(2) {
  [0]=>
  &object(ReflectionMethod)#2 (2) {
    ["name"]=>
    string(11) "__construct"
    ["class"]=>
    string(3) "Dog"
  }
  [1]=>
  &object(ReflectionMethod)#3 (2) {
    ["name"]=>
    string(4) "bark"
    ["class"]=>
    string(3) "Dog"
  }
}
*/
$tmpAry = array();
foreach($methods as $method){
    $tmpAry[] = array(
        'name' => $method->name,
        'param' => $method->getParameters()
    );
}
/*
array(2) {
  [0]=>
  array(2) {
    ["name"]=>
    string(11) "__construct"
    ["param"]=>
    array(1) {
      [0]=>
      &object(ReflectionParameter)#4 (1) {
        ["name"]=>
        string(4) "name"
      }
    }
  }
  [1]=>
  array(2) {
    ["name"]=>
    string(4) "bark"
    ["param"]=>
    array(0) {
    }
  }
}
*/
?>

ReflectionClassのメソッドについて

string ReflectionClass::getName(void)
クラス名を返す。
string ReflectionClass::getDocComment(void)
ドキュメントのコメントを返す。
string ReflectionClass::getFileName
ファイル名を返す。
int ReflectionClass::getStartLine
クラスを宣言してる行番号を返す。
array ReflectionClass::getProperties
プロパティをReflectionPropertyクラスのオブジェクトの配列として返す。
array ReflectionClass::getMethods
メソッドをReflectionMethodクラスのオブジェクトの配列として返す。
string ReflectionClass::getParentClass
親クラスの名前を返す。

■定義済みクラスを調べる

以下のようにget_declared_classes関数を使って、定義済みクラス名を列挙することができる。但し、この関数は後述のget_defined_functions関数と異なり、システム定義とユーザ定義を明確に区別しない。

<?php
class Dog {
	//code
}
var_dump(get_declared_classes());
/*
array(101) {
  [0]=>
  string(8) "stdClass"
  [1]=>
  string(9) "Exception"
  [2]=>
  string(14) "ErrorException"
・・・
  [44]=>
  string(10) "Reflection"
  [45]=>
  string(18) "ReflectionFunction"
  [46]=>
  string(19) "ReflectionParameter"
  [47]=>
  string(16) "ReflectionMethod"
  [48]=>
  string(15) "ReflectionClass"
  [49]=>
  string(16) "ReflectionObject"
  [50]=>
  string(18) "ReflectionProperty"
  [51]=>
  string(19) "ReflectionExtension"
・・・
  [89]=>
  string(12) "PDOException"
  [90]=>
  string(3) "PDO"
  [91]=>
  string(12) "PDOStatement"
・・・
  [100]=>
  string(3) "Dog"
}
*/
?>
array get_declared_classes(void)
宣言済みのクラス名の配列を返す。

■定義済み関数について調べる

定義済み関数を調べるには、以下のようにReflectionFunctionクラスを使う。

<?php
function sample($to = 'world'){
    print('hello, {$to}');
}
$funcs = get_defined_functions();
foreach($funcs['user'] as $key => $value){
	try{
		$func = new ReflectionFunction($value);
	}
	catch(ReflectionException $e){
		//code
	}
	var_dump($func->name);
	var_dump($func->getParameters());
}
/*
string(6) "sample"
array(1) {
  [0]=>
  &object(ReflectionParameter)#2 (1) {
    ["name"]=>
    string(2) "to"
  }
}
*/
?>

また、ReflectionFunctionクラスには以下のように様々なメソッドが用意されている。getParametersメソッドで引数を返し、getFileNameメソッドでファイル名を返し、getStartLineメソッドで関数が記述されている行番号を返すといった感じだ。

<?php
function sample($to = 'world'){
    print('hello, {$to}');
}
function hoge($a, $b = array()){}
$funcs = get_defined_functions();
$tmpAry = array();
foreach($funcs['user'] as $key => $value){
	try{
		$func = new ReflectionFunction($value);
	}
	catch(ReflectionException $e){
		//code
	}
	$args = array();
	foreach($func->getParameters() as $param){
		$arg = '';
		if($param->isPassedByReference()){
			$arg = '&';
		}
		if($param->isOptional()){
			$arg = '[' . $param->getName() . ' = ' .$param->getDefaultValue() . ']';
		}
		else{
			$arg = $param->getName();
		}
		$args[] = $arg;
	}
	$tmpAry[] = array(
		'prototype' => $func->name,
		'file'      => $func->getFileName(),
		'line'      => $func->getStartLine(),
		'arg'       => $args
	);
}
var_dump($tmpAry);
/*
array(2) {
  [0]=>
  array(4) {
    ["prototype"]=>
    string(6) "sample"
    ["file"]=>
    string(57) "/var/www/sample.com/httpdocs/sample.php"
    ["line"]=>
    int(5)
    ["arg"]=>
    array(1) {
      [0]=>
      string(12) "[to = world]"
    }
  }
  [1]=>
  array(4) {
    ["prototype"]=>
    string(4) "hoge"
    ["file"]=>
    string(57) "/var/www/sample.com/httpdocs/sample.php"
    ["line"]=>
    int(8)
    ["arg"]=>
    array(2) {
      [0]=>
      string(1) "a"
      [1]=>
      string(11) "[b = Array]"
    }
  }
}
*/
?>

ReflectionFunctionクラスのメソッドについて

string ReflectionFunction::getName(void)
関数名を返す
string ReflectionFunction::getDocComment(void)
ドキュメントのコメントを返す
string ReflectionFunction::getFileName(void)
ファイル名を返す
int ReflectionFunction::getStartLine(void)
関数を宣言してる行番号を返す
array ReflectionFunction::getParameters(void)
関数の引数をReflectionParameterクラスのオブジェクトの配列として返す

定義済み関数の列挙

PHPでは以下のようにget_defined_functions関数を用いて、定義済み関数を列挙することができる。

<?php
function sample(){
    print('hello!');
}
var_dump(get_defined_functions());
/*
array(2) {
  ["internal"]=>
  array(1510) {
    [0]=>
    string(12) "zend_version"
    [1]=>
    string(13) "func_num_args"
    [2]=>
    string(12) "func_get_arg"
    [3]=>
    string(13) "func_get_args"
    [4]=>
    string(6) "strlen"
    [5]=>
    string(6) "strcmp"
・・・
    [1508]=>
    string(22) "ioncube_loader_version"
    [1509]=>
    string(23) "ioncube_loader_iversion"
  }
  ["user"]=>
  array(1) {
    [0]=>
    string(6) "sample"
  }
}
*/
?>

各関数について

array get_defined_functions(void)
定義済みの全ての関数の名前を配列で返す。

■まとめ

クラスについてはReflectionClassクラスにクラス名を引数として与えると、各メソッドで情報を取得できる。但し、getMethodsメソッドなどは(ReflectionMethodクラスの)オブジェクトの配列を返す。そのオブジェクトに対するメソッドgetParametersは、(ReflectionParameterクラスの)オブジェクトの配列を返す。

関数についてはReflectionFunctionクラスに関数名を引数として与えると、書くメソッドで情報を取得できる。但し、getParametersメソッドなどは(ReflectionParameterクラスの)オブジェクトの配列を返す。

コメントはまだありません»

No comments yet.

RSS feed for comments on this post.TrackBack URL

Leave a comment