PHP反射メカニズムの紹介
5838 ワード
Php Reflection APIはPHP 5ならではの新機能で、クラス、メソッド、属性、パラメータなどの詳細情報を書き出したり抽出したりするためのものです.
よく使われるのは2つだけで、ReflectionClassとReflectionObject、前者はクラス、後者はオブジェクト、後者は前者を継承するクラスです.次に、対応するreflectionオブジェクトを返すプロパティまたはメソッドもあります.
PHP反射機構、クラス、インタフェース、関数、方法と拡張に対して逆工程を行う能力.
クラス、インタフェース、関数、メソッドの内部構造、メソッドと関数のパラメータ、およびクラスの属性とメソッドを分析します.
よく使用されるクラス: ReflectionClass解析クラス ReflectionPropertyクラスの属性に関する情報 ReflectionMethodクラスメソッドに関する情報 ReflectionParameter関数またはメソッドパラメータに関する情報 を取り出す. ReflectionFunction関数に関する情報 サンプルクラス
ReflectionClass
ReflectionProperty
ReflectionMethod & ReflectionParameter
ReflectionFunction & ReflectionParameter
総合例
反射を使用したクラスのインスタンス化
一般的にクラスをインスタンス化するときは直接newが可能であるが,我々は今この方法を用いずに反射を用いて実現している.
ケース1
状況2
この場合,クラスのコンストラクション関数パラメータを解析する際に,パラメータが伝達されなければ,makeメソッドを再帰的に呼び出してStudyクラスを処理し,クラスが存在すればインスタンス化する.PHPの反射はとても使いやすい機能で、ここでは簡単に説明するしかありません.詳しく紹介し、使い方は公式マニュアルを参照してください.
よく使われるのは2つだけで、ReflectionClassとReflectionObject、前者はクラス、後者はオブジェクト、後者は前者を継承するクラスです.次に、対応するreflectionオブジェクトを返すプロパティまたはメソッドもあります.
PHP反射機構、クラス、インタフェース、関数、方法と拡張に対して逆工程を行う能力.
クラス、インタフェース、関数、メソッドの内部構造、メソッドと関数のパラメータ、およびクラスの属性とメソッドを分析します.
よく使用されるクラス:
class Student
{
public $id;
public $name;
const MAX_AGE = 200;
public static $likes = [];
public function __construct($id, $name = 'li')
{
$this->id = $id;
$this->name = $name;
}
public function study()
{
echo 'learning...';
}
private function _foo()
{
echo 'foo';
}
protected function bar($to, $from = 'zh')
{
echo 'bar';
}
}
ReflectionClass
//ReflectionClass
$ref = new ReflectionClass('student');
//
if($ref->isInstantiable()){
echo " ";
}
// , ReflectionMethod , null
$constructor = $ref->getConstructor();
//
if ($ref->hasProperty('id')) {
$attr = $ref->getProperty('id');
}
//
$attributes = $ref->getProperties();
foreach ($attributes as $row){
echo $row->getName()."
";
}
// ,
$static = $ref->getStaticProperties();
//
if ($ref->hasConstant('MAX_AGE')) {
$const = $ref->getConstant('MAX_AGE');
}
//
$constants = $ref->getConstants();
//
if ($ref->hasMethod('bar')) {
$method = $ref->getMethod('bar');
}
//
$methods = $ref->getMethods();
ReflectionProperty
if ($ref->hasProperty('name')) {
$attr = $ref->getProperty('name');
//
echo $attr->getName();
// ,
var_dump($attr->isDefault());
//
$attr->isPrivate();
$attr->isPublic();
$attr->isProtected();
//
$attr->isStatic();
}
ReflectionMethod & ReflectionParameter
$method = $ref->getMethod('bar');
//
//isAbstruct()
//isConstructor()
//isDestructor()
//isFinal()
//isPrivate()
//isPublic()
//isProtected()
//isStatic()
//
$parameters = $method->getParameters();
foreach ($parameters as $row) {
echo $row->getName();
echo $row->getClass();
//
if ($row->isDefaultValueAvailable()) {
echo $row->getDefaultValue();
}
//
if ($row->hasType()) {
echo $row->getType();
}
}
ReflectionFunction & ReflectionParameter
$fun = new ReflectionFunction('demo');
echo $fun->getName();
$parameters = $fun->getParameters();
foreach ($parameters as $row) {
// $row ReflectionParameter
echo $row->getName();
echo $row->getClass();
//
if ($row->isDefaultValueAvailable()) {
echo $row->getDefaultValue();
}
//
if ($row->hasType()) {
echo $row->getType();
}
}
総合例
反射を使用したクラスのインスタンス化
//student.php
class Student
{
public $id;
public $name;
public function __construct($id, $name)
{
$this->id = $id;
$this->name = $name;
}
public function study()
{
echo 'learning.....';
}
}
一般的にクラスをインスタンス化するときは直接newが可能であるが,我々は今この方法を用いずに反射を用いて実現している.
//index.php
require 'student.php';
function make($class, $vars = [])
{
$ref = new ReflectionClass($class);
if ($ref->isInstantiable()) {
$constructor = $ref->getConstructor();
if (is_null($constructor)) {
return new $class;
}
//
$params = $constructor->getParameters();
$resolveParams = [];
foreach ($params as $key => $param) {
$name = $param->getName();
if (isset($vars[$name])) {
// ,
$resolveParams[] = $vars[$name];
} else {
// , , ,
$default = $param->isDefaultValueAvailable() ? $param->isDefaultValueAvailable() : null;
if (is_null($default)) {
if ($param->getClass()) {
$resolveParams[] = make($value->getClass()->name, $vars);
} else {
throw new Exception("{$name} ");
}
} else {
$resolveParams[] = $default;
}
}
}
//
return $ref->newInstanceArgs($resolveParams);
} else {
throw new Exception(" {$class} ");
}
}
ケース1
try {
$stu = make('Student', ['id' => 1, 'name'=>'li']);
print_r($stu);
$stu->study();
} catch(Exception $e) {
echo $e->getMessage();
}
状況2
try {
$stu = make('Student', ['id' => 1, 'name'=>'li', 'study'=> new Study]);
print_r($stu);
$stu->study();
} catch(Exception $e) {
echo $e->getMessage();
}
この場合,クラスのコンストラクション関数パラメータを解析する際に,パラメータが伝達されなければ,makeメソッドを再帰的に呼び出してStudyクラスを処理し,クラスが存在すればインスタンス化する.PHPの反射はとても使いやすい機能で、ここでは簡単に説明するしかありません.詳しく紹介し、使い方は公式マニュアルを参照してください.