php反射机制学习

  PHP 5 具有完整的反射 API,可以通过反射机制来获取类,接口,函数的详细信息。例如可以通过反射api的成员属性,成员方法,命名空间的名称,检测某个类是否为抽象类等操作。(欢迎指点)

一般用途是在框架中配合自动加载类来完成 对类的实例化操作。

  1.建立一个Person类的反射类,然后实例化此类。

<?php
class Person {    
    /**  
     * demo
     */   
    private $_allowDynamicAttributes = false;  
   
    /** demo*/  
    public $id = 0;  
   
    /** demo */  
    protected $name = 'lemon';  
   
    /** demo */  
    protected $biography;  
 
    public function getName()  
    {  
        return $this->name;  
    }  
    public function setName($v)  
    {  
        $this->name = $v;  
    }  
}

//建立 Person这个类的反射类
$class = new ReflectionClass('Person');

//相当于实例化Person 类
$instance  = $class->newInstanceArgs([]);

  2.获取属性

$properties = $class->getProperties(); 
foreach($properties as $property) {  
    echo $property->getName()."
";  
}

   默认情况下,getProperties会获取到所有的属性,pulbic,private,protected.如果只想获取到private属性,就要额外传个参数:

 可用参数列表:

  ReflectionProperty::IS_STATIC
  ReflectionProperty::IS_PUBLIC
  ReflectionProperty::IS_PROTECTED
  ReflectionProperty::IS_PRIVATE
  如果要同时获取public 和private 属性,就这样写:ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PROTECTED。

   3.获取方法

$methods = $class->getMethods(); 
foreach($methods as $method) {  
   echo $method->name.PHP_EOL;
}  

   4.执行方法

//获取Person 类中的getName方法
echo $instance->getName();
//或者
$re = $class->getmethod('getName');
echo $re->invoke($instance); 

    5.和自动加载类配合实例化某类

    目录结构 d代表目录,f代表文件

  Reflection (d)

  Reflection6.php (f)

  loader.php (f)

  ----vendor (d)

    ----A(d)

      ----A.php (f)

     Reflection6.php 文件

<?php
namespace Reflection;

require 'loader.php';
call_user_func_array([new ReflectionClass('vendorAA'),'newInstance'],['demo']);

 loader.php 文件

<?php
function loader($classname)
{
    $fullfile = '';
    if (($index = strripos($classname,'\')) !== false){
        $namespace = substr($classname,0,$index);
        $classname = substr($classname,$index+1).'.php';
        $fullfile = __DIR__.DIRECTORY_SEPARATOR.$namespace.DIRECTORY_SEPARATOR.$file;
        $fullfile = str_replace('\','/',$fullfile);
    }

    if (file_exists($fullfile)) {
        require $fullfile;
    }
}

spl_autoload_register('loader');

    A.php

<?php
namespace vendorA;

class A
{
    private $name = 'zc';
    
    public function __construct()
    {
        echo 'this is '.func_get_args()[0];
    }
        
}

   浏览器输出 this is demo.

原文地址:https://www.cnblogs.com/loveyouyou616/p/5441063.html