Einfaches Tutorial zur PHP-Reflection-API

伊谢尔伦
Freigeben: 2023-03-12 09:14:01
Original
1111 Leute haben es durchsucht

Apropos Reflection-API: Ich bin der Meinung, dass die Reflection-API in PHP dem Paket java.lang.reflect in Java ähnelt. Beide bestehen aus einer Reihe integrierter Klassen, die Klassen drucken und analysieren können Mitgliedsattribute und -methoden. Vielleicht haben Sie bereits Objektfunktionen wie get_class_vars() gelernt, aber die Verwendung der Reflection-API ist flexibler und die Ausgabeinformationen sind detaillierter.

Zunächst müssen wir wissen, dass die Reflection-API nicht nur zum Überprüfen von Klassen verwendet wird, sondern selbst eine Reihe von Klassen zur Ausführung verschiedener Funktionen enthält: Häufig verwendete Klassen sind wie folgt :

Reflection-Klasse
Reflection类 可以打印类的基本信息,(通过提供的静态export()函数)
ReflectionMethod类 见名知意,打印类方法、得到方法的具体信息等
ReflectionClass类 用于得到类信息,比如得到类包含的方法,类本的属性,是不是抽象类等
ReflectionParameter类 显示参数的信息,可以动态得到已知方法的传参情况
ReflectionException类  用于显示错误信息
ReflectionExtension类 得到PHP的扩展信息,可以判断扩展是否存在等
Grundlegende Informationen der Klasse können gedruckt werden (über die bereitgestellte statische export()-Funktion)
ReflectionMethod class="font-family: Microsoft YaHei; color: #008000;"> Kennen Sie die Bedeutung anhand des Namens, drucken Sie Klassenmethoden aus, erhalten Sie spezifische Informationen zu den Methoden usw.
wird verwendet, um Klasseninformationen abzurufen. Beispielsweise werden die in der Klasse enthaltenen Methoden, die Attribute der Klasse, ob es sich um eine abstrakte Klasse handelt usw. abgerufen.
ReflectionParameter-Klasse Parameterinformationen anzeigen, Sie können den Parameterübertragungsstatus bekannter Methoden dynamisch abrufen
ReflectionException-Klasse wird verwendet, um Fehlermeldung anzuzeigen
ReflectionExtension-Klasse Rufen Sie PHP-Erweiterungsinformationen ab, Sie können feststellen, ob die Erweiterung vorhanden ist usw.






Der Unterschied zwischen herkömmlichen Druckinformationen und der Reflexions-API
Das Folgende ist Ein Parameterprogramm, das ich selbst geschrieben habe, um die Verwendung von Reflection zu demonstrieren:

<?php

class Person
{
    //成员属性
    public $name;
    public $age; 

    //构造方法
    public function construct($name, $age)
    {
        $this->name = $name;
        $this->age = $age;
    }

    //成员方法
    public function set_name($name)
    {
        $this->$name = $name;
    }

    public function get_name()
    {
        return $this->$name;
    }

    public function get_age()
    {
        return $this->$age;
    }

    public function get_user_info()
    {
        $info = &#39;姓名:&#39; . $this->name;
        $info .= &#39; 年龄:&#39; . $this->age;
        return $info;
    }
}

class Teacher extends Person
{
    private $salary = 0;

    public function construct($name, $age, $salary)
    {
        parent::construct($name, $age);
        $this->salary = $salary;
    }

    public function get_salary()
    {
        return $this->$salary;
    }

    public function get_user_info()
    {
        $info = parent::get_user_info();
        $info .= " 工资:" . $this->salary;
        return $info;
    }
}

class Student extends Person
{
    private $score = 0;

    public function construct($name, $age, $score)
    {
        parent::construct($name, $age);
        $this->score = $score;
    }

    public function get_score()
    {
        return $this->score;        
    }

    public function get_user_info()
    {
        $info = parent::get_user_info();
        $info .= " 成绩:" . $this->score;
        return $info;
    }
}

header("Content-type:text/html;charset=utf8;");
$te_obj = new Teacher(&#39;李老师&#39;, &#39;36&#39;, &#39;2000&#39;);
$te_info = $te_obj->get_user_info();

$st_obj = new Student(&#39;小明&#39;, &#39;13&#39;, &#39;80&#39;);
$st_info = $st_obj->get_user_info();
Nach dem Login kopieren

Wir verwenden zuerst var_dump(); um Klasseninformationen zu drucken, wie unten gezeigt, das können Sie nur beim Drucken sehen Um einfache Informationen über die Klasse herauszubekommen, gibt es nicht einmal eine Methode, sodass aus solchen Informationen keine anderen Schwimminformationen ersichtlich sind.

var_dump($te_obj);

object(Teacher)#1 (3) {
      ["salary":"Teacher":private]=>
          string(4) "2000"
      ["name"]=>
          string(9) "李老师"
      ["age"]=>
          string(2) "36"
}
Nach dem Login kopieren

 Reflection::export($obj);

Wir verwenden die von Reflection bereitgestellte integrierte Methode Export, um Informationen zu drucken, wie unten gezeigt:

Die gedruckten Informationen sind relativ vollständig, einschließlich der Mitglieder Attribute, Mitgliedermethode, grundlegende Informationen der Klasse, Dateipfad, Methodeninformationen, Methodenattribute, Parameterübertragungsstatus, Anzahl der Zeilen in der Datei usw. Eine relativ umfassende Anzeige von Klasseninformationen. Es ist ersichtlich, dass var_dump () oder print_r nur kurze Informationen zur Klasse anzeigen können und viele Informationen überhaupt nicht angezeigt werden können, sodass sie nur zum einfachen Debuggen verwendet werden können. Die Reflexions-API bietet weitere Informationen zur Klasse. Dies kann eine gute Hilfe sein. Wir kennen die Situation beim Aufrufen von Klassen, was das Schreiben von Schnittstellen, insbesondere das Aufrufen von Schnittstellen anderer Personen, sehr erleichtert. Es kann auch beim Debuggen hilfreich sein, wenn etwas schief geht.

object(Teacher)#1 (3) {
      ["salary":"Teacher":private]=>
          string(4) "2000"
      ["name"]=>
          string(9) "李老师"
      ["age"]=>
          string(2) "36"
}
Class [  class Person ] {
      @@ /usr/local/www/phptest/oop/reflaction.php 3-38
      - Constants [0] {
      }
      - Static properties [0] {
      }
      - Static methods [0] {
 }
  - Properties [2] {
        Property [  public $name ]
        Property [  public $age ]
  }

  - Methods [5] {
    Method [  public method construct ] {
      @@ /usr/local/www/phptest/oop/reflaction.php 10 - 14

      - Parameters [2] {
        Parameter #0 [  $name ]

.....
Nach dem Login kopieren

Spezifische Verwendung der Reflection-API:

Schüler, die den Framework-Quellcode gelesen haben, wissen, dass jeder Framework kann verwendet werden. Laden Sie Plug-Ins, Klassenbibliotheken usw. von Drittanbietern. Im folgenden Beispiel verwenden wir die Reflection-API, um diese Funktion einfach zu implementieren. Nachdem ich den Prototyp dieses Beispiels verstanden habe, habe ich einen Satz nach meinen eigenen Vorstellungen geschrieben: Zu realisierende Funktion: Verwenden Sie eine Klasse, um sie dynamisch zu implementieren Durchlaufen und Aufrufen der Eigenschaftsklasse. Objekte und Klassen können Methoden anderer Klassen frei laden, ohne die Klasse in vorhandenen Code einbetten oder den Code der Klassenbibliothek manuell aufrufen zu müssen.
Konvention: Jede Klasse muss eine Arbeitsmethode enthalten und kann eine Schnittstelle abstrahieren. Sie können die Informationen jeder Klasse in die Datei einfügen, was den Informationen jeder Klassenbibliothek entspricht, und dann die Arbeitsmethode jeder Klassenbibliothek über das entsprechende Objekt der von der Klasse gespeicherten Eigenschaftsklassenbibliothek aufrufen.

Das Folgende ist der Basiscode:

/*属性接口*/
interface Property
{
    function work();
}

class Person
{
    public $name;
    public function construct($name)
    {
        $this->name = $name;
    }
}

class StudentController implements Property
{
    //set方法,但需要Person对象参数
    public function setPerson(Person $obj_person)
    {
        echo &#39;Student &#39; . $obj_person->name;
    }

    //work方法简单实现
    public function work()
    {
        echo &#39;student working!&#39;;
    }
}

class EngineController implements Property
{
    //set方法
    public function setWeight($weight)
    {
        echo &#39;this is engine -> set weight&#39;;
    }

    public function setPrice($price)
    {
        echo "this is engine -> set price";
    }

    //work方法简单实现
    public function work()
    {
        echo &#39;engine working!&#39;;
    }
}
Nach dem Login kopieren

Hier werden zwei ähnliche Klassen definiert, um die Property-Schnittstelle zu implementieren, und beide werden einfach implementiert work() Die Methode der StudentController-Klasse ist etwas anders. Die Parameter erfordern ein Person-Objekt. Gleichzeitig können wir stattdessen auch Mitgliedsattribute verwenden.

class Run
{
    public static $mod_arr = [];
    public static $config = [
        &#39;StudentController&#39; => [
            &#39;person&#39; => &#39;xiao ming&#39;
        ],
        &#39;EngineController&#39;  => [
            &#39;weight&#39; => &#39;500kg&#39;,
            &#39;price&#39;  => &#39;4000&#39;
        ]
    ];

    //加载初始化
    public function construct()
    {
        $config = self::$config;
        //用于检查是不是实现类
        $property = new ReflectionClass(&#39;Property&#39;);
        foreach ($config as $class_name => $params) {
            $class_reflect = new ReflectionClass($class_name);
            if(!$class_reflect->isSubclassOf($property)) {//用isSubclassOf方法检查是否是这个对象
                echo &#39;this is  error&#39;;
                continue;
            }

            //得到类的信息
            $class_obj = $class_reflect->newInstance();
            $class_method = $class_reflect->getMethods();

            foreach ($class_method as $method_name) {
                $this->handle_method($class_obj, $method_name, $params);
            }
            array_push(self::$mod_arr, $class_obj);
        }
    }

    //处理方法调用
    public function handle_method(Property $class_obj, ReflectionMethod $method_name, $params)
    {
        $m_name = $method_name->getName();
        $args = $method_name->getParameters();

        if(count($args) != 1 || substr($m_name, 0, 3) != &#39;set&#39;) {    
            return false;
        }
        //大小写转换,做容错处理
        $property = strtolower(substr($m_name, 3));
     
        if(!isset($params[$property])) {
            return false;
        }

        $args_class = $args[0]->getClass();
        echo &#39;<pre class="brush:php;toolbar:false">&#39;;
        if(empty($args_class)) {
            $method_name->invoke($class_obj, $params[$property]); //如果得到的类为空证明需要传递基础类型参数
        } else {
            $method_name->invoke($class_obj, $args_class->newInstance($params[$property])); //如果不为空说明需要传递真实对象
        }
    }
}

//程序开始
new Run();
Nach dem Login kopieren

Am Ende dieses Programms ruft Run Startup automatisch den Konstruktor auf, um andere Mitgliedseigenschaften der zu ladenden Klassenbibliothek zu initialisieren, einschließlich der Initialisierung und Ausführung entsprechender Methodenoperationen . Dies ist gerade abgeschlossen. Das Attribut $mod_arr speichert alle Objekte der aufrufenden Klasse. Jedes Objekt enthält Daten, und die enthaltenen Objekte können durchlaufen werden, um die work()-Methode aufzurufen.

Das Programm dient nur zum Verständnis der Reflexions-PAI. Es werden viele Reflexions-API-Klassen und -Methoden verwendet .

Reflection API Gemeinsame Klassen und Funktionen bereitgestellt:

Die unten bereitgestellten Funktionen sind nicht vorhanden Alle häufig verwendeten Funktionen werden verwendet, und einige Funktionen werden überhaupt nicht verwendet. Daher haben wir über diejenigen geschrieben, die lügen. Wenn Sie sie alle sehen möchten, können Sie online suchen, es gibt viele. Es ist nicht erforderlich, sich die bereitgestellten Methoden zu merken. Sie können sie bei der Verwendung überprüfen.

1:Reflection
  public static export(Reflector r [,bool return])//打印类或方法的详细信息
  public static  getModifierNames(int modifiers)  //取得修饰符的名字

2:ReflectionMethod:
    public static string export()                       //打印该方法的信息
    public mixed invoke(stdclass object, mixed* args)   //调用对应的方法
    public mixed invokeArgs(stdclass object, array args)//调用对应的方法,传多参数
    public bool isFinal()        //方法是否为final
    public bool isAbstract()     //方法是否为abstract
    public bool isPublic()       //方法是否为public
    public bool isPrivate()      //方法是否为private
    public bool isProtected()    //方法是否为protected
    public bool isStatic()       //方法是否为static
    public bool isConstructor()  //方法是否为构造函数

3:ReflectionClass:
    public static string export()  //打印类的详细信息
    public string getName()        //取得类名或接口名
    public bool isInternal()       //类是否为系统内部类
    public bool isUserDefined()    //类是否为用户自定义类
    public bool isInstantiable()   //类是否被实例化过
    public bool hasMethod(string name)  //类是否有特定的方法
    public bool hasProperty(string name)//类是否有特定的属性
    public string getFileName()         //获取定义该类的文件名,包括路径名
    public int getStartLine()           //获取定义该类的开始行
    public int getEndLine()             //获取定义该类的结束行
    public string getDocComment()       //获取该类的注释
    public ReflectionMethod getConstructor()           //取得该类的构造函数信息
    public ReflectionMethod getMethod(string name)     //取得该类的某个特定的方法信息
    public ReflectionMethod[] getMethods()             //取得该类的所有的方法信息
    public ReflectionProperty getProperty(string name) //取得某个特定的属性信息
    public ReflectionProperty[] getProperties()        //取得该类的所有属性信息
    public array getConstants()                        //取得该类所有常量信息
    public mixed getConstant(string name)              //取得该类特定常量信息
    public ReflectionClass[] getInterfaces()           //取得接口类信息
    public bool isInterface()  //测试该类是否为接口
    public bool isAbstract()   //测试该类是否为抽象类

4:ReflectionParameter:
    public static string export()     //导出该参数的详细信息
    public string getName()           //取得参数名
    public bool isPassedByReference() //测试该参数是否通过引用传递参数
    public ReflectionClass getClass() //若该参数为对象,返回该对象的类名
    public bool isArray()             //测试该参数是否为数组类型
    public bool allowsNull()          //测试该参数是否允许为空
    public bool isOptional()          //测试该参数是否为可选的,当有默认参数时可选
    public bool isDefaultValueAvailable() //测试该参数是否为默认参数
    public mixed getDefaultValue()        //取得该参数的默认值

5:ReflectionExtension类
    public static  export()    //导出该扩展的所有信息
    public string getName()    //取得该扩展的名字
    public string getVersion() //取得该扩展的版本
    public ReflectionFunction[] getFunctions()   //取得该扩展的所有函数
    public array getConstants()  //取得该扩展的所有常量
    public array getINIEntries() //取得与该扩展相关的,在php.ini中的指令信息
}
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonEinfaches Tutorial zur PHP-Reflection-API. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage