Introduction à la réflexion du framework API PHP manuscrit (3)

藏色散人
Libérer: 2023-04-11 10:32:02
avant
4247 Les gens l'ont consulté

Dans l'article précédent "Framework API PHP manuscrit - Installation et utilisation de Composer (2)", nous avons présenté l'installation et l'utilisation de Composer. Dans cet article, nous présenterons le concept de réflexion.

La réflexion, la compréhension intuitive consiste à trouver le point de départ et la source en fonction du lieu d'arrivée. La réflexion fait référence à l'extension de l'analyse des programmes PHP dans l'état d'exécution de PHP, à l'exportation ou à la proposition d'informations détaillées sur les classes, méthodes, propriétés, paramètres, etc., y compris des commentaires. Cette fonction d'obtention dynamique d'informations et d'appel dynamique de méthodes objet est appelée API de réflexion.

Jetons d'abord un coup d'œil à une démo :

<?php


function p($msg, $var)
{
    echo($msg.":".print_r($var, true)).PHP_EOL.PHP_EOL;
}


class Demo
{
    private $id;

    protected $name;

    public $skills = [];

    public function __construct($id, $name, $skills = [])
    {
        $this->id = $id;
        $this->name = $name;
        $this->skills = $skills;
    }

    public function getName()
    {
        return $this->name;
    }
    public function getSkill()
    {
        p(&#39;skill&#39;, $this->skills);
    }
}


$ref = new ReflectionClass(&#39;Demo&#39;);
if ($ref->isInstantiable()) {
    p(&#39;检查类是否可实例化isInstantiable&#39;, null);
}
$constructor = $ref->getConstructor();
p(&#39;获取构造函数getConstructor&#39;, $constructor);

$parameters = $constructor->getParameters();
foreach ($parameters as $param) {
    p(&#39;获取参数getParameters&#39;, $param);
}

if ($ref->hasProperty(&#39;name&#39;)) {
    $attr = $ref->getProperty(&#39;name&#39;);
    p(&#39;获取属性getProperty&#39;, $attr);
}

$attributes = $ref->getProperties();
foreach ($attributes as $row) {
    p(&#39;获取属性列表getProperties&#39;, $row->getName());
}

if ($ref->hasMethod(&#39;getSkill&#39;)) {
    $method = $ref->getMethod(&#39;getSkill&#39;);
    p(&#39;获取方法getMethod&#39;, $method);
}

$methods = $ref->getMethods();
foreach ($methods as $row) {
    p(&#39;获取方法列表getMethods&#39;, $row->getName());
}

$instance = $ref->newInstanceArgs([1, &#39;sai&#39;, [&#39;php&#39;, &#39;js&#39;]]);
p(&#39;newInstanceArgs&#39;, $instance);
Copier après la connexion

Sortie :

➜  php git:(main) php reflect.php 

检查类是否可实例化isInstantiable:

获取构造函数getConstructor:ReflectionMethod Object
(
    [name] => __construct
    [class] => Demo
)


获取参数getParameters:ReflectionParameter Object
(
    [name] => id
)


获取参数getParameters:ReflectionParameter Object
(
    [name] => name
)


获取参数getParameters:ReflectionParameter Object
(
    [name] => skills
)


获取属性getProperty:ReflectionProperty Object
(
    [name] => name
    [class] => Demo
)


获取属性列表getProperties:id

获取属性列表getProperties:name

获取属性列表getProperties:skills

获取方法getMethod:ReflectionMethod Object
(
    [name] => getSkill
    [class] => Demo
)


获取方法列表getMethods:__construct

获取方法列表getMethods:getName

获取方法列表getMethods:getSkill

newInstanceArgs:Demo Object
(
    [id:Demo:private] => 1
    [name:protected] => sai
    [skills] => Array
        (
            [0] => php
            [1] => js
        )

)
Copier après la connexion

La classe ReflectionClass est utilisée dans la démo Bien entendu, la classe ReflectionClass ne se limite pas à ces méthodes.

Plus de méthodes

La classe ReflectionClass a beaucoup plus de méthodes :

Méthode Description
ReflectionClass::__construct Initialiser la classe ReflectionClass
ReflectionClass::export Exporter une classe
ReflectionClass::getConstant Obtenir le défini Une constante
ReflectionClass::getConstants Obtenir un ensemble de constantes
ReflectionClass::getConstructor Obtenir le constructeur de la classe
ReflectionClass::getDefaultProperties Obtenir le propriétés par défaut
ReflectionClass: ; ReflectionClass: ; ionClass ::getInterfaces Obtenir l'interface
ReflectionClass::getMethod Obtenir la ReflectionMethod d'une méthode de classe.
ReflectionClass::getMethods Obtenir le tableau des méthodes
ReflectionClass::getModifiers Obtenir les modificateurs de la classe
ReflectionClass::getName Obtenir le nom de la classe
Classe de Réflexion ::getNamespaceName Obtenir le nom de l'espace de noms
ReflectionClass::getParentClass Obtenir la classe parent
ReflectionClass::getProperties Obtenir un ensemble de propriétés
ReflectionClass::getPro perty Obtenez un attribut d'une classe ReflectionProperty
ReflectionClass::getReflectionConstant Obtient un ReflectionClassConstant pour la constante d'une classe
ReflectionClass::getReflectionConstants Obtient des constantes de classe
hortName Obtenez le nom court
ReflectionClass: ; ReflectionClass:: getTraitAliases Renvoie un tableau d'alias de traits
ReflectionClass::getTraitNames Renvoie un tableau de noms de traits utilisés par cette classe
ReflectionClass::getTraits Renvoie un tableau des traits utilisés par cette classe
ReflectionClass::hasConstant Vérifiez si la constante a été définie
ReflectionClass::hasMethod Vérifiez si la méthode a été définie
ReflectionClass::hasProperty Vérifiez si la propriété a été définie. le la classe est une classe abstraite (abstract)
ReflectionClass::is Anonymous Vérifiez si la classe est une classe anonyme
ReflectionClass::isCloneable Renvoie si une classe est copiable
ReflectionClass:: isFinal Vérifiez si la classe est déclarée finale
ReflectionClass::isInstance vérifiez les instances des classes
ReflectionClass::isInstantiable Vérifiez si la classe est instanciable
ReflectionClass::is Interface Vérifiez si la classe est une interface
ReflectionClass::isInternal Vérifiez si la classe est définie en interne par extension ou par noyau
ReflectionClass::isIterable Vérifiez si cette classe est itérable
ReflectionClass:: isIterateable Vérifie si itérable (itérable)
ReflectionClass::isSubclassOf Vérifie s'il s'agit d'une sous-classe
ReflectionClass::isTrait renvoie s'il s'agit d'un trait
ReflectionClass ::isUserDefined Vérifiez s'il est défini par l'utilisateur
ReflectionClass::newInstance From Les arguments spécifiés créent une nouvelle instance de classe
ReflectionClass::newInstanceArgs Crée une nouvelle instance de classe à partir des arguments donnés.
ReflectionClass::newInstanceWithoutConstructor Créer une nouvelle instance de classe sans appeler son constructeur
ReflectionClass::setStaticPropertyValue Définir la valeur d'une propriété statique
ReflectionClass::__toString Return ReflectionClass La chaîne représentation de l'objet.

En plus du puissant ReflectionClass, il existe également Reflection, ReflectionClassConstant, ReflectionMethod, ReflectionFunctionAbstract, etc. Il est recommandé de consulter le manuel :

Application pratique de Reflection

  • Reflection peut être utilisé pour la génération de documents et de fichiers. Vous pouvez l'utiliser pour analyser les classes du fichier et générer des documents de description un par un 

  • Étant donné que la réflexion peut détecter la structure interne de la classe, vous pouvez l'utiliser comme un hook pour implémenter des fonctions de plug-in ;

  • peut être utilisé pour créer des proxys dynamiques. Générer et instancier dynamiquement certaines classes et méthodes d'exécution lorsque le nom de la classe est inconnu ou incertain.
  • Injection de dépendances. Pour les classes qui héritent plusieurs fois, nous pouvons explorer la structure de la classe de base à travers plusieurs réflexions, ou utiliser la réflexion récursive pour instancier toutes les classes héritées. C'est aussi le principe de l'injection de dépendances PHP.
Avantages de la réflexion

    Les langages qui prennent en charge la réflexion fournissent certaines fonctionnalités d'exécution difficiles à implémenter dans les langages de bas niveau.
  • peut éviter le codage en dur dans une certaine mesure et offrir flexibilité et polyvalence.
  • peut être utilisé comme objet de première classe pour découvrir et modifier la structure du code source (comme les blocs de code, les classes, les méthodes, les protocoles, etc.).
  • Vous pouvez calculer des chaînes de syntaxe symbolique au moment de l'exécution, tout comme les instructions du code source (similaire à la fonction eval() de JavaScript), puis convertir les chaînes correspondant à une classe ou une fonction en appels ou références à une classe ou une fonction.
  • Il est possible de créer un nouvel interpréteur de bytecode de langage pour donner aux constructions de programmation une nouvelle signification ou un nouveau but.
Inconvénients de la réflexion

    Coût d'apprentissage élevé. La programmation orientée réflexion nécessite des connaissances plus avancées, notamment les frameworks, le mappage relationnel et l'interaction d'objets, afin de tirer parti d'une exécution de code plus générale.
  • De plus, parce que le concept et la syntaxe de la réflexion sont relativement abstraits, un abus excessif de la technologie de réflexion entraînera faire Le code est difficile à comprendre pour les autres, ce qui n'est pas propice à la coopération et à la communication
  • Bien que la réflexion améliore la flexibilité du code, elle sacrifie un peu d'efficacité opérationnelle et a une certaine consommation
  • La réflexion sera détruisez également l'encapsulation de la classe, exposant des méthodes ou des attributs qui ne devraient pas être exposés
  • Dans le développement quotidien, nous n'utilisons pas beaucoup la réflexion, alors pourquoi l'amener ici ? Premièrement, nous utiliserons la réflexion plus tard pour implémenter le conteneur Ioc. Deuxièmement, la réflexion est également l'une des fonctions essentielles de PHP. Elle est très courante dans nos frameworks populaires, et il est nécessaire de la comprendre.

Cette section est relativement indépendante, nous l'utiliserons dans les chapitres suivants.

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!

Étiquettes associées:
source:juejin.im
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal