Le mécanisme de réflexion de PHP permet aux développeurs de vérifier les informations structurelles des classes, des interfaces, des fonctions, des méthodes et des extensions lors de l'exécution. Pour donner l'exemple le plus simple, nous pouvons utiliser ReflectionMethod pour obtenir des informations de paramètres d'une certaine méthode de classe:
<code> $ méthode = new ReflectionMethod (myClass :: class, 'myMethod'); $ params = $ méthode-> getParameters (); </code>Cela nous permet de connaître le nombre de paramètres, le nom, les invites de type, etc. de la méthode, mais il n'effectuera pas automatiquement la vérification de type.
IS_A () est une fonction qui détermine si un objet est une certaine classe ou sa sous-classe au moment de l'exécution. La syntaxe est la suivante:
<code> is_a ($ objet, $ classname, $ allow_string = false) </code>Son avantage est sa forte dynamicité et convient particulièrement à une utilisation avec le mécanisme de réflexion pour la vérification des types.
Supposons que nous construisons un conteneur d'injection de dépendance qui est responsable de l'injection automatique des paramètres en fonction de la signature de la méthode. Pour des raisons de sécurité, nous voulons nous assurer que l'objet injecté est conforme aux contraintes de type définies par la méthode.
Voici un exemple d'utilisation de la réflexion + IS_A pour implémenter la vérification du type strict:
<code> Fonction invokeWithDependces ($ className, $ methodname, array $ dépendances) {$ RefMethod = new ReflectionMethod ($ className, $ methodname); $ params = $ RefMethod-> getParameters (); $resolvedParams = [];
foreach ($params as $param) {
$paramType = $param->getType();
if ($paramType && !$paramType->isBuiltin()) {
$expectedClass = $paramType->getName();
$matched = false;
foreach ($dependencies as $dep) {
if (is_object($dep) && is_a($dep, $expectedClass)) {
$resolvedParams[] = $dep;
$matched = true;
break;
}
}
if (!$matched) {
throw new InvalidArgumentException("No matching dependency for parameter \${$param->getName()} of type $expectedClass");
}
} else {
// Type non objet,Sauter ou utiliser des valeurs par défaut
$resolvedParams[] = $param->isDefaultValueAvailable() ? $param->getDefaultValue() : null;
}
}
return $refMethod->invokeArgs(new $className(), $resolvedParams);
}
</code>
Dans cet exemple, nous comparons l'objet dans le tableau de dépendances $ pour refléter les types de paramètres de méthode obtenus par réflexion et utiliser is_a () pour garantir que l'objet est en effet le type requis par le paramètre ou sa sous-classe. Si aucune dépendance de correspondance n'est trouvée, une exception est lancée pour éviter les appels avec un décalage dans le type.
Combiné avec le conteneur d'injection de dépendance : lors de l'enregistrement d'une instance dans le conteneur de service, le nom de classe est enregistré et injecté automatiquement par réflexion et is_a () lors de l'appel.
Traitement des interfaces et des classes abstraites : IS_A () est également applicable aux interfaces et aux classes abstraites, et peut être utilisée pour la mise en œuvre automatique de l'interface d'injection.
Utilisez $ allow_string = true avec prudence : Bien qu'il soit flexible d'activer les noms de classe de chaîne, il est facile de briser la sécurité de type à moins d'avoir un contrôle très strict sur l'appelant.