企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
### :-: **介绍** **PHP中的反射API(Reflection)属于比较高级的特性,很多朋友没有深入学习,可能没有听说过,这里我们深入研究一下反射的意义。** ***** 反射由一系列可以分析属性、方法和类的内置类组成。它在某些方面和对象函数相似,比如`get_class_vars()`,但是更加灵活,而且可以提供更多信息。反射API也可与PHP最新的面向对象特性一起工作,如访问控制、接口和抽象类。旧的类函数则不太容易与这些新特性一起使用。看过框架源码的朋友应该对PHP的反射机制有一定的了解,像是依赖注入,对象池,类加载,一些设计模式等等,都用到了反射机制。 ***** 通俗的理解就是定义了一个类,通常来讲大部分时候只要 new 这个类,得到他的实例,调用他实例的方法就可以运用了,但是如果现在我们想得到这些信息 > 这个类是否有定义构造函数? > 构造函数又需要传几个参数? > 这个类有哪些属性? > 属性都是否为常量? > 这个类有哪些方法? > 每个方法的访问修饰符是什么(public/protected/private)? > 每个方法要传哪些参数? > 每个参数有什么要求,比如有没强制指定参数类型?参数有没有有默认值? > 等等。。。 这里我们引用一个图,这是反射类的继承图,每个类的作用都有说明,详细api查阅手册 http://www.php.net/manual/zh/book.reflection.php ![](https://box.kancloud.cn/ac4f0e38ff05135204ebc17edc888959_2452x1465.jpg) ### :-: **实例** **构建一个简单的类** ``` <?php class Student { public $name; protected $age; private $sex; public function __construct($name , $age , $sex) { $this->setName($name); $this->setAge($age); $this->setSex($sex); } public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } protected function setAge($age) { $this->age = $age; } private function setSex($sex) { $this->sex = $sex; } } ``` **建立反射类示例** ``` <?php require_once 'Student.php'; //两种方法建立一个类的反射 //方法1,实例化后传入对象到 ReflectionClass $obj = new Student('张三' ,'33 ,' ,0); $class = new ReflectionClass($obj); //方法2 直接传类名到 ReflectionClass $class = new ReflectionClass('Student'); //实例化 Student 类 //方法1 $instance = $class->newInstanceArgs(array( '张三' , 33 , 0, )); //方法2 $instance = $class->newInstance('张三' ,'33 ,' ,0); //两种方法等同于 $instance = new Student('张三' ,'33 ,' ,0) //print_r($class); //print_r($instance);exit;; //执行他的方法 $res = $instance->getName(); //var_dump类的所有属性和方法 //$res = ReflectionClass::export('Person'); //$res = $class::export('Person'); //$res = $class-> __toString (); //返回指定常量 //$res = $class->getConstant('aaa'); //返回所有定义过的常量 //$res = $class->getConstants(); //反射了类的构造函数 //$res = $class->getConstructor (); //获取指定属性,包括private的 //$res = $class->getProperty('name'); //$res = $res->getName(); //获取所有属性,包括private的 //$res = $class->getProperties(); //获取文档注释 //$res = $class->getDocComment(); // 获取最后一行的行数 //$res = $class->getEndLine(); // 获取起始的行号 //$res = $class->getStartLine(); // 获取类被定义的文件的文件名。 //$res = $class->getFileName (); // 获取类名 //$res = $class->getName (); // 获取方法的数组 // ReflectionMethod::IS_PUBLIC 、 ReflectionMethod::IS_PROTECTED 、 ReflectionMethod::IS_PRIVATE 、 ReflectionMethod::IS_ABSTRACT 、 ReflectionMethod::IS_FINAL 的任意组合。 //$res = $class->getMethods (ReflectionMethod::IS_PUBLIC); //获取getName方法对象 //ReflectionMethod //$res = $class->getMethod('getName'); //执行方法 //$res = $res->invoke($instance); ``` **通过反射类调用方法示例** >[danger] > **thinkphp 5.0 底层在执行我们定义的控制器的方法就是使用的这个方式 参考 App 类里的 invokeMethod 静态方法** ``` //调用方法示例 $obj = new Student('张三' ,'33 ,' ,0); $class = new ReflectionClass($obj); $instance = $class->newInstance('张三' ,'33 ,' ,0); //建立方法的反射 $method = new ReflectionMethod("Student" , 'setName'); //调用 setName 这个方法 $res = $method->invokeArgs($instance , array( '李四' , )); ```