ホームページ >バックエンド開発 >PHPチュートリアル >PHPのリフレクション機構の使い方を詳しく解説

PHPのリフレクション機構の使い方を詳しく解説

王林
王林オリジナル
2019-09-02 09:50:384654ブラウズ

PHPのリフレクション機構の使い方を詳しく解説

リフレクション

オブジェクト指向プログラミングでは、オブジェクトにはイントロスペクションの機能が与えられ、このイントロスペクションのプロセスがリフレクションです。

熟考、直観的理解とは、到着地に基づいて出発地と発信源を見つけることです。たとえば、裸のオブジェクトの場合、そのオブジェクトが属するクラスと、そのオブジェクトがどのようなメソッドを持っているかを、このオブジェクトを通じて知ることができます。

リフレクションとは、PHP の実行状態で PHP プログラムの分析を拡張し、クラス、メソッド、プロパティ、パラメーターなどに関するコメントを含む詳細情報をエクスポートまたは提案することを指します。この動的に情報を取得し、オブジェクトのメソッドを動的に呼び出す機能をリフレクションAPIと呼びます。

リフレクション API の使用方法?

<?php
class person{
public $name;
public $gender;
public function say(){
  echo $this->name," \tis ",$this->gender,"\r\n";
}
public function set($name, $value) {
  echo "Setting $name to $value \r\n";
  $this->$name= $value;
}
public function get($name) {
  if(!isset($this->$name)){
    echo &#39;未设置&#39;;
       
     $this->$name="正在为你设置默认值";
  }
  return $this->$name;
  }
}
$student=new person();
$student->name=&#39;Tom&#39;;
$student->gender=&#39;male&#39;;
$student->age=24;

さて、この Student オブジェクトのメソッドとプロパティのリストを取得するにはどうすればよいでしょうか?次のコードに示すように:

// 获取对象属性列表
$reflect = new ReflectionObject($student);
$props = $reflect->getProperties();
foreach ($props as $prop) {
  print $prop->getName() ."\n";
}
// 获取对象方法列表
$m=$reflect->getMethods();
foreach ($m as $prop) {
  print $prop->getName() ."\n";
}

リフレクション API を使用せずにクラス関数を使用して、オブジェクトのプロパティと詳細情報の連想配列を返すこともできます:

// 返回对象属性的关联数组
var_dump(get_object_vars($student));
// 类属性
var_dump(get_class_vars(get_class($student)));
// 返回由类的方法名组成的数组
var_dump(get_class_methods(get_class($student)));

このオブジェクトが他のオブジェクトから渡された場合ページ ここに来て、それがどのカテゴリに属しているかどうやってわかりますか?たった 1 行のコードでこれを実行できます:

// 获取对象属性列表所属的类
echo get_class($student);

リフレクション API の機能は明らかにより強力で、メソッドのアクセス許可などを含むこのクラスのプロトタイプを復元することもできます。例:

// 反射获取类的原型
$obj = new ReflectionClass(&#39;person&#39;);
$className = $obj->getName();
$Methods = $Properties = array();
foreach($obj->getProperties() as $v)
{
    $Properties[$v->getName()] = $v;
}
foreach($obj->getMethods() as $v)
   
 {
    $Methods[$v->getName()] = $v;
}
echo "class {$className}\n{\n";
is_array($Properties)&&ksort($Properties);
foreach($Properties as $k => $v)
{
    echo "\t";
    echo $v->isPublic() ? &#39; public&#39; : &#39;&#39;,$v->isPrivate() ? &#39; private&#39; : &#39;&#39;,
    $v->isProtected() ? &#39; protected&#39; : &#39;&#39;,
    $v->isStatic() ? &#39; static&#39; : &#39;&#39;;
    echo "\t{$k}\n";
}
echo "\n";
if(is_array($Methods)) ksort($Methods);
foreach($Methods as $k => $v)
{
    echo "\tfunction {$k}(){}\n";
}
echo "}\n";

出力は次のとおりです:

class person
{
  public gender
  public name
  function get(){}
  function set(){}
  function say(){}
}

それだけでなく、PHP マニュアルには数十のリフレクション API が記載されています。クラスまたはオブジェクトのプロトタイプ。リフレクションはクラスやオブジェクトだけでなく、関数、拡張モジュール、例外などにも使用できます。

リフレクションは何をするのでしょうか?

リフレクションはドキュメント生成に使用できます。したがって、これを使用してファイル内のクラスをスキャンし、説明ドキュメントを 1 つずつ生成できます。

リフレクションはクラスの内部構造を検出できるため、プラグイン関数を実装するためのフックとして使用できますか?それとも動的プロキシですか?

例:

<?php
class mysql {
  function connect($db) {
    echo "连接到数据库${db[0]}\r\n";
  }
}
class sqlproxy {
  private $target;  
  function construct($tar) { 
    $this->target[] = new $tar();
  }
  function call($name, $args) {
    foreach ($this->target as $obj) {
      $r = new ReflectionClass($obj);
      if ($method = $r->getMethod($name)) {
        if ($method->isPublic() && !$method->isAbstract()) {
          echo "方法前拦截记录LOG\r\n";
          $method->invoke($obj, $args);
          echo "方法后拦截\r\n";
        }
      }
    }
  }
}
$obj = new sqlproxy(&#39;mysql&#39;);
$obj->connect(&#39;member&#39;);

通常の開発では、リフレクションが使用される場所はそれほど多くありません。1 つはオブジェクトのデバッグで、もう 1 つはクラス情報の取得です。 MVC やプラグインの開発では、リフレクションの使用が非常に一般的ですが、リフレクションは非常に高価でもあるため、代替手段が見つかった場合は乱用しないでください。

多くの場合、リフレクションをうまく利用すると、コードをエレガントで簡潔に保つことができますが、リフレクションにより、公開すべきでないメソッドやプロパティが強制的に公開される可能性があるため、クラスのカプセル化が破壊される可能性もあります。メリットでもありデメリットでもあります。

関連コンテンツをさらに知りたい場合は、PHP 中国語 Web サイトにアクセスしてください: PHP ビデオ チュートリアル

以上がPHPのリフレクション機構の使い方を詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。