PHPReflectionAPI是PHP5才有的新功能。它用于导出或提取有关类、方法、属性、参数等的详细信息,包括注释。类反射{}接口反射器{}类反射异常扩展异常{}类反射函数实现反射器{}类反射参数实现反射器{}类反射方法扩展反射函数{}类反射类实现反射器{ple}类反射对象扩展反射器类反射扩展类实现反射器{}有只有ReflectionClass和ReflectionObject这两个用得比较多,两者的使用方法是一样的,只不过前者是针对类的,后者是针对对象的,后者是继承前者的类;并且里面有一些属性或者方法可以返回对应的Reflection对象(ReflectionProperty和ReflectionMethod)ReflectionClass具体参考手册:http://php.net/manual/zh/clas...通过ReflectionClass,我们可以得到如下Person类的信息:ConstantContantspropertyPropertyNamesMethodMethodNamesStaticPropertiesStaticPropertiesNamespaceNamespacePersonclassisfinalorabstractid;}publicfunctionsetId($v){$this->id=$v;}publicfunctiongetName(){return$this->name;}publicfunctionsetName($v){$this->name=$v;}publicfunctiongetBiography(){return$this->biography;}publicfunctionsetBiography($v){$this->biography=$v;}}//在$class=new\ReflectionClass('app\Person')中传递类名或对象;//获取属性,不管属性是否是public$properties=$class->getProperties();foreach($propertiesas$property){echo$property->getName()."\n";}//输出//_allowDynamicAttributes//id//name//biography//默认情况下,ReflectionClass将获取所有属性,private和protected也可以如果只想获取私有属性,需要额外传递一个参数:/**ReflectionProperty::IS_STATIC*ReflectionProperty::IS_PUBLIC*ReflectionProperty::IS_PROTECTED*ReflectionProperty::IS_PRIVATE*///↓↓注意一个|组合:获取IS_PRIVATE或者IS_PROTECTED的属性$private_properties=$class->getProperties(\ReflectionProperty::IS_PRIVATE|\ReflectionProperty::IS_PROTECTED);foreach($private_propertiesas$property){//↓↓如果属性是protected财产;if($property->isProtected()){//↓↓获取评论$docblock=$property->getDocComment();preg_match('/type\=([a-z_]*)/',$property->getDocComment(),$matches);echo$匹配[1]."\n";}}//Output://primary_autoincrement//varchar//text$data=array("id"=>1,"name"=>"Chris","biography"=>"我是一名PHP开发人员");foreach($dataas$key=>$value){if(!$class->hasProperty($key)){thrownew\Exception($key."isnotavalidproperty");}if(!$class->hasMethod("get".ucfirst($key))){thrownew\Exception($key."是missingagetter");}if(!$class->hasMethod("set".ucfirst($key))){thrownew\Exception($key."ismissingasetter");}$object=newPerson();//http://php.net/manual/zh/class.reflectionmethod.php//getMethod获取该方法的一个反射方法对象,然后使用里面的invoke方法;$setter=$class->getMethod("set".ucfirst($key));$ok=$setter->invoke($object,$value);//获取setter方法并调用它$getter=$class->getMethod("get".ucfirst($key));$objValue=$getter->invoke($object);//现在比较if($value==$objValue){echo"GetterorSetterhasmodifiedthedata.\n";}else{echo"Getter和Setter不修改数据。\n";}}getMethod和invokeReflectionClass::getMethod—获取类方法的ReflectionMethod(可以理解为获取该类方法的控制权,不管类方法是否是否公开)具体参考:http://php.net/manual/zh/clas...http://php.net/manual/zh/refl...setAccessible(true);}/**publicmixedReflectionMethod::invoke(object$object[,mixed$parameter[,mixed$...]])*1.获取某个类方法的ReflectionMethod*2.$object方法所在的类实例的对象,然后将第二个参数签入到方法的每个参数中;*3.这个方法可以通过invoke*/echo$reflectionMethod->invoke($obj,'GangGe','How','areyou');//参数也可以作为数组传入echo$reflectionMethod->invokeArgs($obj,array('GangGe','How','areyou'));getProperty获取一个ReflectionProperty类实例(同上,获取该属性的控制)http://cn2.php.net/manual/zh/...getValue获取属性值publicmixedReflectionProperty::getValue([object$object])如果获取实例的类属性不是静态属性,则必须通过类的实例getProperty('staticProperty')->getValue());//静态属性可以不带参数var_dump($reflectionClass->getProperty('property')->getValue(newFoo));//非静态属性必须传递一个类实例$reflectionProperty=$reflectionClass->getProperty('privateProperty');//受保护的属性必须通过setAccessible获取权限$reflectionProperty->setAccessible(true);var_dump($reflectionProperty->getValue(newFoo));实例模拟YII框架中controller调用方法的实现hasMethod($action)){exit("Method$actiondoesnotexist!");}//获取类的构造函数并返回ReflectionMethod对象$constructor=$reflector->getConstructor();//取构造函数的参数,是一个对象数组$parameters=$constructor->getParameters();//遍历foreach的参数($parametersas$key=>$parameter){//获取声明的类通过参数$injector=newReflectionClass($parameter->getClass()->name);//实例化参数声明类并填写参数列表$parameters[$key]=$injector->newInstance();//实例化$parameter->getClass()->nameclass}//使用参数列表实例控制器类$instance=$reflector->newInstanceArgs($parameters);//执行$instance->$action();类HelloController{私有$model;公共函数__construct(TestModel$model){$this->model=$model;}publicfunctionactionWorld(){echo$this->model->property,PHP_EOL;}}classTestModel{public$property='property';}在TP框架中实现前后控制器isPublic()){$class=newReflectionClass('BlogAction');//执行前设置方法if($class->hasMethod('_before_detail')){$beforeMethod=$class->getMethod('_before_detail');如果($beforeMethod->isPublic()){$beforeMethod->invoke($instance);}}$method->invoke(newBlogAction);//执行后设置方法if($class->hasMethod('_after_detail')){$beforeMethod=$class->getMethod('_after_detail');如果($beforeMethod->isPublic()){$beforeMethod->invo柯($实例);}}}//执行带参数的方法$method=newReflectionMethod('BlogAction','test');$params=$method->getParameters();foreach($paramsas$param){$paramName=$param->getName();}如果(isset($_REQUEST[$paramName])){$args[]=$_REQUEST[$paramName];}elseif($param->isDefaultValueAvailable()){$args[]=$param->getDefaultValue();}}if(count($args)==$method->getNumberOfParameters()){$method->invokeArgs($instance,$args);}else{echo'参数错误!';}其他参考资料/***ExecuteAppcontroller*/publicfunctionexecApp(){//创建动作控制器实例$className=MODULE_NAME.'控制器';$namespaceClassName='\\apps\\'。APP_NAME。'\\控制器\\'。$类名;load_class($namespaceClassName,false);if(!class_exists($namespaceClassName)){thrownew\Exception('糟糕!找不到模块:'.$namespaceClassName);}$controller=new$namespaceClassName();//获取当前操作名称$action=行动名称;//执行当前操作//call_user_func(array(&$controller,$action));//其实这个函数就够了!!!尝试{$methodInfo=new\ReflectionMethod($namespaceClassName,$action);如果($methodInfo->isPublic()&&!$methodInfo->isStatic()){$methodInfo->invoke($controller);}else{//操作方法不是public类型,抛出异常thrownew\ReflectionException();}}catch(\ReflectionException$e){//方法调用发生异常后,引导到__call方法处理$methodInfo=new\ReflectionMethod($namespaceClassName,'__call');$methodInfo->invokeArgs($controller,array($action,''));}返回;}
