Comprendre le mécanisme
PHPStan réduit un type après certaines conditions et peut comprendre des fonctions de garde annotées avec phpstan-assert. Cette annotation est une promesse de comportement à vérifier dans le corps de la fonction. Une assertion documentaire qui ment peut conduire l’analyse à accepter un accès invalide. L’instruction assert de PHP ne doit pas porter seule une validation de sécurité indispensable, car sa configuration d’exécution peut la rendre inactive.
Raisonner et vérifier
Utilisez des conditions exécutées qui refusent le cas invalide. Testez la garde et ses chemins de retour, puis décrivez exactement ce qu’elle garantit. Elle peut établir une forme de donnée sans prouver son authenticité ou son autorisation. Évitez les PHPDocs locaux qui écrasent le type d’une donnée externe seulement pour faire passer la CI.
Garde exécutable
Une garde doit exécuter son refus. L’annotation décrit une promesse du code. Une fonction requireText doit tester réellement chaîne et non-vacuité, puis refuser le reste. Son annotation phpstan-assert décrit la propriété qui devient vraie après un retour normal de cette fonction.
Erreur fréquente à comprendre
phpstan-assert génère le corps de validation.
L’annotation décrit une promesse du code.
Annotation trompeuse
Une annotation fausse peut tromper l’analyse. Le contrat doit être vérifié et testé. Un commentaire local peut affirmer qu’une valeur est un User alors que le réseau a fourni un entier. Préférez établir le type à la frontière et conserver une preuve visible dans le flot de contrôle.
Erreur fréquente à comprendre
L’analyse corrige automatiquement toute promesse mensongère.
Le contrat doit être vérifié et testé.
Configuration assert
assert PHP dépend de sa configuration d’exécution. Une validation indispensable doit avoir un refus garanti. Les assertions PHP peuvent être désactivées selon la configuration de compilation et d’exécution. Une validation indispensable doit rester un contrôle explicite dont l’absence ne dépend pas d’une option d’optimisation.
Erreur fréquente à comprendre
assert est toujours une garde de sécurité active en production.
Une validation indispensable doit avoir un refus garanti.
Branches d’une union
Une condition peut réduire une union. La preuve doit correspondre au chemin réellement pris. Dans une branche où value est une string, strlen devient cohérent. Vérifiez le chemin des autres types et la sortie de chaque branche ; une condition sans refus ne protège pas le code placé ensuite.
Erreur fréquente à comprendre
Une condition non exécutée valide quand même l’entrée réseau.
La preuve doit correspondre au chemin réellement pris.
Chaîne non vide
non-empty-string n’est pas une preuve d’innocuité HTML. Le contexte de sortie exige d’autres contrôles. Un texte '<script>' est non vide. L’innocuité HTML, le paramétrage SQL et l’admission d’une destination URL nécessitent des protections propres à leur contexte, distinctes de la simple longueur.
Erreur fréquente à comprendre
Toute chaîne non vide est sûre pour innerHTML.
Le contexte de sortie exige d’autres contrôles.
Tester le refus
Un refus de garde doit être testé. Les chemins invalides demandent une vérification réelle. Appelez la garde avec null, chaîne vide et type inattendu. Une exception attendue et l’absence d’effet aval démontrent que l’annotation décrit bien un contrôle exécuté, plutôt qu’une convention ignorée.
Erreur fréquente à comprendre
Le seul PHPDoc suffit à prouver les exceptions.
Les chemins invalides demandent une vérification réelle.
Authenticité distincte
Un type précis ne prouve pas l’authenticité. Le type et la provenance sont deux propriétés. Une structure de jeton correctement typée peut être forgée. La signature, l’émetteur et le destinataire demandent leur validation ; un objet Claims n’établit pas à lui seul une relation de confiance.
Erreur fréquente à comprendre
Une chaîne de type correct est nécessairement signée.
Le type et la provenance sont deux propriétés.
PHPDoc local
Les PHPDocs locaux doivent rester honnêtes. Il peut masquer l’incertitude au lieu de la résoudre. Réservez les annotations locales aux limites réellement connues et explicables de l’analyse. Si une validation manque dans le programme, ajoutez ce code au lieu de modifier uniquement l’information donnée à l’outil.
Erreur fréquente à comprendre
Un @var inventé est une correction de toute donnée externe.
Il peut masquer l’incertitude au lieu de la résoudre.
Structure et droit
Une garde de structure ne donne pas de droit métier. Le modèle de permissions reste distinct. Une entrée contenant projectId:int peut viser le projet d’un tiers. Après validation structurelle, chargez la ressource dans le bon périmètre et appliquez la décision d’autorisation avant la mutation.
Erreur fréquente à comprendre
Une array shape valide autorise toute opération.
Le modèle de permissions reste distinct.
Exception explicite
Une exception explicite peut imposer le rejet. Le comportement doit respecter la promesse de validation. Une InvalidArgumentException permet de couper le chemin invalide. L’analyse peut alors déduire le type sur le chemin restant ; testez aussi que le gestionnaire d’erreur public ne divulgue pas la valeur sensible refusée.
Erreur fréquente à comprendre
Une garde peut retourner normalement sur toute entrée invalide.
Le comportement doit respecter la promesse de validation.
Atelier guidé : lire, expliquer et vérifier le code
<?php
declare(strict_types=1);
/** @phpstan-assert non-empty-string $value */
function requireText(mixed $value): void {
// aucune garde exécutée
}
requireText(null);
echo 'continued'; Dans l’extrait, le corps ne fait rien et null traverse la fonction. L’annotation ne produit donc aucun arrêt à l’exécution. Ajoutez une garde dont le retour normal garantit exactement non-empty-string, puis testez valeur vide, null et valeur admise sans dépendre d’assert PHP.
Le commentaire n’exécute pas le refus ; le programme continue. Aucun contrôle PHP natif n’est généré par ce PHPDoc. Aucune opération de validation ou transformation ne le fait. L’analyse ne réécrit pas la fonction.
Travail pratique : Retirez temporairement la condition dans le laboratoire, comparez l’analyse puis testez null et chaîne vide à l’exécution.
Critères de correction : La promesse peut tromper l’analyse si le corps ment. Restaurez la garde et ajoutez des tests des entrées invalides, puis vérifiez que les usages contextuels restent contrôlés.
Exemple commenté
<?php
declare(strict_types=1);
/** @phpstan-assert non-empty-string $value */
function requireNonEmpty(mixed $value): void
{
if (!is_string($value) || $value === '') {
throw new InvalidArgumentException('Chaîne requise');
}
}Le refus réel justifie la promesse non-empty-string. Cela n’assainit pas cette chaîne pour tous les contextes.
Exercice de mise en pratique
Retirez temporairement la condition dans le laboratoire, comparez l’analyse puis testez null et chaîne vide à l’exécution.
Voir une proposition de correction
La promesse peut tromper l’analyse si le corps ment. Restaurez la garde et ajoutez des tests des entrées invalides, puis vérifiez que les usages contextuels restent contrôlés.
Points de vérification
- Garde réelle.
- Promesse exacte.
- Tests des refus.
Contrôle de connaissances
Cours associé : 05. Réduction de types et assertions honnêtes ↗Validation du module
101 questions, objectif pédagogique de 75 %. Durée conseillée de 150 minutes, sans limite imposée. Les questions et les choix sont mélangés ; le corrigé apparaît après validation. Le contrôle rapide de la leçon et l’examen final du cours restent des exercices distincts.
Commencer ou reprendre les 101 questions →Cette marque suit votre propre avancement ; elle ne certifie pas la maîtrise du sujet. Effectuez l’exercice avant de passer à la suite.
