Maison  >  Article  >  développement back-end  >  Compréhension approfondie du mécanisme de réflexion en PHP

Compréhension approfondie du mécanisme de réflexion en PHP

青灯夜游
青灯夜游avant
2021-06-08 18:49:153194parcourir

Cet article vous donnera une introduction détaillée au mécanisme de réflexion en PHP. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer. J'espère qu'il sera utile à tout le monde.

Compréhension approfondie du mécanisme de réflexion en PHP

Le mécanisme de réflexion de PHP fournit un ensemble d'API de réflexion permettant d'accéder et d'utiliser des classes, des méthodes, des propriétés, des paramètres et des annotations, etc., par exemple via un objet. Connaissant la classe à laquelle appartient cet objet, les méthodes que contient cette classe, les paramètres dans lesquels ces méthodes doivent être transmises, le type de chaque paramètre, etc., vous pouvez accéder aux membres et aux méthodes de la classe sans créer d'instance de la classe. , même si les membres de la classe sont définis comme privés. Également accessible en externe.

La documentation officielle fournit des classes de réflexion telles que ReflectionClass、ReflectionMethod、ReflectionObject、ReflectionExtension et les API correspondantes. La plus couramment utilisée est ReflectionClass.

Afin de démontrer l'effet de réflexion, créez d'abord une classe (en supposant qu'un utilisateur de classe soit défini) et instanciez-la. Sur la base de cette instance, la classe réflexive peut accéder aux propriétés et méthodes dans User.

<?php
/**
 * 用户相关类
 */
class User {
    public $username;
    private $password;

    public function __construct($username, $password)
    {
        $this->username = $username;
        $this->password = $password;
    }

    /**
     * 获取用户名
     * @return string
     */
    public function getUsername()
    {
        return $this->username;
    }

    /**
     * 设置用户名
     * @param string $username
     */
    public function setUsername($username)
    {
        $this->username = $username;
    }

    /**
     * 获取密码
     * @return string
     */
    private function getPassword()
    {
        return $this->password;
    }

    /**
     * 设置密码
     * @param string $password
     */
    private function setPassowrd($password)
    {
        $this->password = $password;
    }
}

Créer une instance de classe de réflexion

$refClass = new ReflectionClass(new User(&#39;liulu&#39;, &#39;123456&#39;));

// 也可以写成 
$refClass = new ReflectionClass(&#39;User&#39;); // 将类名User作为参数,建立User类的反射类

Attribut de réflexion

$properties = $refClass->getProperties(); // 获取User类的所有属性,返回ReflectionProperty的数组
$property = $refClass->getProperty(&#39;password&#39;); // 获取User类的password属性
//$properties 结果如下:
Array (
   [0] => ReflectionProperty Object ( [name] => username [class] => User )
   [1] => ReflectionProperty Object ( [name] => password [class] => User )
)   
//$property 结果如下:
ReflectionProperty Object ( [name] => password [class] => User )

Méthode de réflexion

$methods = $refClass->getMethods(); // 获取User类的所有方法,返回ReflectionMethod数组
$method = $refClass->getMethod(&#39;getUsername&#39;);  // 获取User类的getUsername方法

//$methods 结果如下:
Array (
    [0] => ReflectionMethod Object ( [name] => __construct [class] => User )
    [1] => ReflectionMethod Object ( [name] => getUsername [class] => User )
    [2] => ReflectionMethod Object ( [name] => setUsername [class] => User )
    [3] => ReflectionMethod Object ( [name] => getPassword [class] => User )
    [4] => ReflectionMethod Object ( [name] => setPassowrd [class] => User )
)
//$method 结果如下:
ReflectionMethod Object ( [name] => getUsername [class] => User )

Annotation de réflexion

$classComment = $refClass->getDocComment();  // 获取User类的注释文档,即定义在类之前的注释
$methodComment = $refClass->getMethod(&#39;setPassowrd&#39;)->getDocComment();  // 获取User类中setPassowrd方法的注释
//$classComment 结果如下:
/** * 用户相关类 */
//$methodComment 结果如下:
/** * 设置密码 * @param string $password */

Instanciation de réflexion

$instance = $refClass->newInstance(&#39;admin&#39;, 123, &#39;***&#39;);  // 从指定的参数创建一个新的类实例
//$instance 结果如下:
User Object ( [username] => admin [password:User:private] => 123 )
注:虽然构造函数中是两个参数,但是newInstance方法接受可变数目的参数,用于传递到类的构造函数。 

$params = [&#39;xiaoming&#39;, &#39;asdfg&#39;];
$instance = $refClass->newInstanceArgs($params); // 从给出的参数创建一个新的类实例
//$instance 结果如下:
User Object ( [username] => xiaoming [password:User:private] => asdfg )

Accéder et exécuter les méthodes publiques de la classe - public

$instance->setUsername(&#39;admin_1&#39;); // 调用User类的实例调用setUsername方法设置用户名
$username = $instance->getUsername(); // 用过User类的实例调用getUsername方法获取用户名
echo $username . "\n"; // 输出 admin_1

// 也可以写成
$refClass->getProperty(&#39;username&#39;)->setValue($instance, &#39;admin_2&#39;); // 通过反射类ReflectionProperty设置指定实例的username属性值
$username = $refClass->getProperty(&#39;username&#39;)->getValue($instance); // 通过反射类ReflectionProperty获取username的属性值
echo $username . "\n"; // 输出 admin_2

// 还可以写成
$refClass->getMethod(&#39;setUsername&#39;)->invoke($instance, &#39;admin_3&#39;); // 通过反射类ReflectionMethod调用指定实例的方法,并且传送参数
$value = $refClass->getMethod(&#39;getUsername&#39;)->invoke($instance); // 通过反射类ReflectionMethod调用指定实例的方法
echo $value . "\n"; // 输出 admin_3

Accéder et exécuter des méthodes non publiques de la classe - privées, protégées

try {
    // 正确写法
    $property = $refClass->getProperty(&#39;password&#39;); // ReflectionProperty Object ( [name] => password [class] => User )
    $property->setAccessible(true); // 修改 $property 对象的可访问性
    $property->setValue($instance, &#39;987654321&#39;); // 可以执行
    $value = $property->getValue($instance); // 可以执行
    echo $value . "\n";   // 输出 987654321

    // 错误写法
    $refClass->getProperty(&#39;password&#39;)->setAccessible(true); // 临时修改ReflectionProperty对象的可访问性
    $refClass->getProperty(&#39;password&#39;)->setValue($instance, &#39;password&#39;); // 不能执行,抛出不能访问异常
    $refClass = $refClass->getProperty(&#39;password&#39;)->getValue($instance); // 不能执行,抛出不能访问异常
    $refClass = $instance->password;   // 不能执行,类本身的属性没有被修改,仍然是private
} catch (Exception $e){
    echo $e;
}

// 错误写法 结果如下:
ReflectionException: Cannot access non-public member User::password in xxx.php

Résumé

Indépendamment des attributs et méthodes définis dans le classe de réflexion Que ce soit public ou non, cela peut être obtenu. L'accès direct aux propriétés et méthodes de protected ou private lèvera une exception. L’accès aux membres non publics nécessite l’appel de la méthode ReflectionProperty ou ReflectionMethod objet setAccessible(true) spécifiée.

Apprentissage recommandé : "Tutoriel vidéo PHP"

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer