Maison  >  Article  >  développement back-end  >  Exemples de code détaillés de la technologie de réflexion PHP (images et textes)

Exemples de code détaillés de la technologie de réflexion PHP (images et textes)

黄舟
黄舟original
2017-03-11 10:23:442999parcourir

Résumé

Par rapport à la réflexion en Java, la réflexion en PHP est vraiment un travail de conscience. Bien que du point de vue de la maintenance, Java soit supérieur et présente plus d'avantages. Cependant, la lourdeur du traitement ajoute également un certain coût d'apprentissage au mécanisme de réflexion de Java.

Aujourd'hui, j'ai essayé d'utiliser la technologie de réflexion de PHP pour obtenir des informations sur les cours.
Les opérations de base peuvent être vues dans le document d'aide officiel de PHP. Les plus couramment utilisées ici sont. Pour démontrer les résultats et la maintenance de la réflexion, créons d'abord une classe avec la structure de répertoires suivante :

getProperties
getMethods

Exemples de code détaillés de la technologie de réflexion PHP (images et textes)

Problème de chargement

Mécanisme de chargement


Avant d'effectuer officiellement l'opération de réflexion, discutons d'abord du Exemples de code détaillés de la technologie de réflexion PHP (images et textes) mécanisme de chargement automatique. Comme son nom l'indique, il se charge automatiquement (classes ou autres fichiers PHP).

<?phpclass Person {
    private $name;    private $age;    private $address;    public function __construct($name, $age, $address) {
        $this->name = $name;        $this->age = $age;        $this->address = $address;
    }    public function setter($key, $value) {
        exec ( "{$this}->" . $key . "={$value}" );
    }    /**
     * 通配型的getter方法不好用。
     * <br />
     * 原因: Object Person can not be converted to string.
     * 
     * @param unknown $key         
     * @return string
     */
    public function getter($key) {
        return exec ( "$this" . "->{$key}" );
    }    /**
     * 模拟Java语言实现的getter方法。<br />
     *
     * 缺点: 需要为每一个private属性提供单独的getter方法,使得代码略显臃肿。
     */
    public function getName() {
        return $this->name;
    }
}class Grade {
    private $name;    public function __construct($name) {
        $this->name = $name;
    }    public function setName($name) {
        $this->name = $name;
    }    public function getName() {
        return $this->name;
    }
}
Pour un niveau plus profond, cela implique le principe de fonctionnement de l'interpréteur PHP. En d’autres termes, on ne peut pas écrire un seul fichier PHP pour un projet. Au contraire, il peut y avoir des centaines de fichiers PHP dans un projet, et ils s’appelleront inévitablement.

En d'autres termes, nous déclarons et implémentons une fonction d'addition dans le fichier A, et devons l'appeler dans le fichier B. Évidemment, cet ajout n’est pas du tout implémenté dans le fichier B, donc l’interpréteur PHP ne peut pas effectuer l’opération d’ajout.

À ce stade, vous devez faire savoir à l'interpréteur PHP comment faire cet ajout, vous avez donc besoin

du fichier A qui contient cette fonction d'ajout. __autoload

De cette manière, l'interpréteur PHP sait interpréter et exécuter nos fichiers PHP.

Semblable à PHP, dans le langage Java, il suffit d'ajouter l'instruction

devant le fichier source, et la machine virtuelle Java peut automatiquement ajouter les informations de classe pertinentes. De plus, Java fortement typé peut détecter de tels problèmes avant la compilation, ce qui rend la maintenance du code plus pratique. Et PHP doit être fait manuellement

. require / include

Mais il doit être clair que les deux changent simplement la soupe mais pas le médicament.


Mécanisme de chargement automatiqueimportinclude/requireMais si vous chargez manuellement chaque fichier php à référencer, vous devrez peut-être écrire plusieurs instructions de chargement de ce type. Par conséquent, afin de faciliter la gestion de ce problème, PHP5 a introduit un mécanisme de chargement automatique.

est le nom de la classe à charger. Veuillez noter qu'il s'agit du nom de
.

Comment utiliser ?

void __autoload ( string $class )
Puisque le mécanisme de chargement automatique est si bon, comment l'utilisons-nous ?

$classLa réponse est d'ajouter une fonction personnalisée en PHP qui doit charger d'autres fichiers de classe. Prenons tout à l'heure le fichier AB comme exemple.


Il y a une classe écrite Personne dans le fichier A, qui doit être utilisée dans le fichier B. À ce stade, ajoutez simplement une fonction

dans le fichier B. De plus, la méthode d’écriture de cette fonction est relativement simple (si tout est conçu selon l’idée la plus simple).

Lorsque l'interpréteur PHP analysera le fichier B, il le vérifiera d'abord. Si la classe cible Person n'est pas introduite, il déterminera si elle a été implémentée

Si elle existe, elle le fera. utilisez la fonction de chargement automatique pour le charger, sinon une erreur sera signalée et quittée. __autoload($class)

Remarques

__aotoloadBien que la fonction de chargement automatique ci-dessus soit relativement simple, en réalité elle nécessite beaucoup de "prix", c'est-à-dire que le nom du fichier de classe chargé doit être cohérent avec la classe Cohérent (aucune sensibilité à la casse n'est requise). Tels que :

function __autoload($class) {
    $filename = "$class.class.php";    
    if(!file_exists($filename)){        
    throw new RuntimeException("$filename 文件不存在!");
    }else {        require "$filename";
    }
}

De plus, le problème du chemin est également un problème difficile à voir dans cette simple fonction de chargement automatique. Ici, ils se trouvent dans le même répertoire. non satisfait. Dans ce cas, vous pouvez connaître la taille du volume de code de cette fonction de chargement automatique. __autoload

Dans ce cas, cela violerait également l'intention initiale du mécanisme de chargement automatique. Par conséquent, il est très nécessaire de stocker les fichiers de classe associés selon une structure de répertoires spécifique.

Ce qu'on appelle : il ajoute des fonctionnalités redondantes, mais apporte l'avantage d'une maintenance facile.

要加载的类的名称为Person,
则该类所在的文件的名称需要为person.class.php,或者Person.class.php

Personnellement, je pense qu'il est préférable de maintenir le programme PHP selon la structure des répertoires du langage Java, ce qui rapportera des gains inattendus.

Réflexion

Nous entrons maintenant officiellement dans le sujet de la réflexion, qui a été évoqué dans la section résumé. Le point clé réside dans l’utilisation de

.

Attribut de réflexion

ReflectionClassPar rapport à Java, il est plus facile d'obtenir l'attribut

en PHP.

Méthode de réflexion
<?phprequire &#39;./bean/beans.php&#39;;
// Person 在beans.php文件中声明$protype = new ReflectionClass("Person");
// 可以添加一个参数,来进行过滤操作。如只获取public类型的属性
$properties = $protype->getProperties();
// 反射获取到类的属性信息
foreach ($properties as $property) {    
echo $property."<br />";
}

Exemples de code détaillés de la technologie de réflexion PHP (images et textes)

privateDe plus, vous pouvez ajouter des conditions de filtre. Donnez simplement à la méthode getMethods Tianji un paramètre de filtre.

filter过滤结果为仅包含某些属性的方法。默认不过滤。 

ReflectionMethod::IS_STATIC、 
ReflectionMethod::IS_PUBLIC、 
ReflectionMethod::IS_PROTECTED、 
ReflectionMethod::IS_PRIVATE、 
ReflectionMethod::IS_ABSTRACT、 
ReflectionMethod::IS_FINAL 的任意组合。

反射注释

注释信息,这里就以文档信息为例。

<?phprequire &#39;./bean/beans.php&#39;;
$protype = new ReflectionClass ( "Person" );
$properties = $protype->getProperties ();
// 反射获取到类的属性信息
foreach ( $properties as $property ) {    
echo $property . ":";    
$doc = $property->getDocComment ();    
echo "   " . $doc . "<br />";    e
cho "--------------------------------------------------------" . "<br />";
}$methods = $protype->getMethods();
foreach ($methods as $method) {    
echo $method->getName()."<br />";   
 $doc = $method->getDocComment ();    
 echo "   " . $doc . "<br />";    
 echo "--------------------------------------------------------" . "<br />";
}

Exemples de code détaillés de la technologie de réflexion PHP (images et textes)

反射实例化

Exemples de code détaillés de la technologie de réflexion PHP (images et textes)

<?phprequire &#39;./bean/beans.php&#39;;
$protype = new ReflectionClass ( "Person" );// 模拟数据库中获取到的值,以关联数组的形式抛出
$values = array(    "name"=>"郭璞",    "age"=> 21,    "address"=>"辽宁省大连市");// 开始实例化
$instance = $protype->newInstanceArgs($values);    
print_r($instance);// 
var_dump($instance);
echo $instance->getName();

Exemples de code détaillés de la technologie de réflexion PHP (images et textes)

反射Grade类

<?phprequire &#39;./bean/beans.php&#39;;$classprotype = new ReflectionClass("Grade");$class = $classprotype->newInstanceArgs(array("name"=>"大三"));
var_dump($class);echo $class->getName();

Exemples de code détaillés de la technologie de réflexion PHP (images et textes)

执行类的方法

$instance->getName(); 
// 执行Person 里的方法getName// 或者:
$method = $class->getmethod(&#39;getName&#39;); 
// 获取Person 类中的getName方法$method->invoke($instance);    
// 执行getName 方法// 或者:$method = $class->getmethod(&#39;setName&#39;); 
// 获取Person 类中的setName方法$method->invokeArgs($instance, array(&#39;snsgou.com&#39;));

总结

回顾一下,本次试验演示了PHP中的反射技术,对比分析了Java语言的反射技术的实现。也只能说各有利弊吧。

在Java中,反射技术是编写框架的基础。虽然在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:
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