Phan est un analyseur statique pour PHP qui préfère minimiser les faux positifs. Phan tente de prouver l'inexactitude plutôt que l'exactitude.
Phan recherche les problèmes courants et vérifiera la compatibilité des types sur diverses opérations lorsque les informations de type sont disponibles ou peuvent être déduites. Phan a une bonne compréhension (mais pas complète) du contrôle de flux et peut suivre les valeurs dans quelques cas d'utilisation (par exemple, tableaux, entiers et chaînes).
La façon la plus simple d’utiliser Phan est via Composer.
composer require phan/phan
Une fois Phan installé, vous souhaiterez créer un fichier .phan/config.php
dans votre projet pour indiquer à Phan comment analyser votre code source. Une fois configuré, vous pouvez l'exécuter via ./vendor/bin/phan
.
Phan 5 dépend de PHP 7.2+ avec l'extension php-ast (1.1.1+ est préféré) et prend en charge l'analyse de la syntaxe PHP version 7.0-8.2. Les instructions d'installation de php-ast peuvent être trouvées ici. (Phan peut être utilisé sans php-ast en utilisant l'option CLI --allow-polyfill-parser
, mais il existe de légères différences dans l'analyse des commentaires de la documentation)
Le Wiki contient plus d'informations sur l'utilisation de Phan.
Phan est capable d'effectuer les types d'analyses suivants :
object
, void
, iterable
, ?T
, [$x] = ...;
, décalages de chaîne négatifs, plusieurs captures d'exceptions, etc.)--dead-code-detection
)--unused-variable-detection
)--redundant-condition-detection
)use
inutilisées. Ces types de problèmes et quelques autres peuvent être automatiquement résolus avec --automatic-fix
.@template
).int[]
, UserObject[]
, array<int,UserObject>
, etc.array{key:string,otherKey:?stdClass}
, etc. (en interne et dans les balises PHPDoc). Cela prend également en charge l'indication que les champs d'une forme de tableau sont facultatifs via array{requiredKey:string,optionalKey?:string}
(utile pour @param
)@deprecated
pour les classes, méthodes et fonctions obsolètes@internal
pour les éléments (tels qu'une constante, une fonction, une classe, une constante de classe, une propriété ou une méthode) comme étant internes au package dans lequel il est défini.@suppress <ISSUE_TYPE>
pour supprimer les problèmes.@property <union_type> <variable_name>
)@method <union_type> <method_name>(<union_type> <param1_name>)
)class_alias
(expérimentales, désactivées par défaut)@phan-closure-scope
(exemple)array_map
, array_filter
et à d'autres fonctions de tableau internes.pcntl
)Voir Types de problèmes Phan pour des descriptions et des exemples de tous les problèmes pouvant être détectés par Phan. Jetez un œil au PhanIssue pour voir la définition de chaque type d’erreur.
Jetez un œil au didacticiel d'analyse d'une grande base de code bâclée pour avoir une idée de ce à quoi pourrait ressembler le processus d'analyse continue pour vous.
Phan peut être utilisé à partir de divers éditeurs et IDE pour sa vérification des erreurs, sa prise en charge « aller à la définition », etc. via le protocole Language Server. Les éditeurs et les outils peuvent également demander l'analyse de fichiers individuels dans un projet en utilisant le mode démon plus simple.
Voir le répertoire tests pour quelques exemples des différentes vérifications.
Phan est imparfait et ne doit pas être utilisé pour prouver que votre système de guidage de fusée basé sur PHP est exempt de défauts.
Des fonctionnalités d'analyse supplémentaires ont été fournies par des plugins.
{ throw new Exception("Message"); return $value; }
)*printf()
par rapport aux arguments fournis (ainsi que vérification des erreurs courantes)preg_*()
sont valides@suppress
qui ne sont plus nécessaires.Exemple : les plugins de Phan pour l'auto-analyse.
Après avoir installé Phan, Phan doit être configuré avec des détails sur l'endroit où trouver le code à analyser et comment l'analyser. Le moyen le plus simple d'indiquer à Phan où trouver le code source est de créer un fichier .phan/config.php
. Un simple fichier .phan/config.php
pourrait ressembler à ceci.
<?php
/ * *
* This configuration will be read and overlaid on top of the
* default configuration . Command line arguments will be applied
* after this file is read .
* /
return [
// Supported values : `'5.6'` , `'7.0'` , `'7.1'` , `'7.2'` , `'7.3'` , `'7.4'` ,
// `'8.0'` , `'8.1'` , `'8.2'` , `'8.3'` , `null` .
// If this is set to `null` ,
// then Phan assumes the PHP version which is closest to the minor version
// of the php executable used to execute Phan .
" target_php_version " => null ,
// A list of directories that should be parsed for class and
// method information . After excluding the directories
// defined in exclude_analysis_directory_list , the remaining
// files will be statically analyzed for errors .
//
// Thus , both first - party and third - party code being used by
// your application should be included in this list .
' directory_list ' => [
' src ' ,
' vendor/symfony/console ' ,
],
// A directory list that defines files that will be excluded
// from static analysis , but whose class and method
// information should be included .
//
// Generally , you ' ll want to include the directories for
// third - party code ( such as "vendor/" ) in this list .
//
// n . b .: If you ' d like to parse but not analyze 3 rd
// party code , directories containing that code
// should be added to the `directory_list` as
// to `exclude_analysis_directory_list` .
" exclude_analysis_directory_list " => [
' vendor/ '
],
// A list of plugin files to execute .
// Plugins which are bundled with Phan can be added here by providing their name
// ( e . g . 'AlwaysReturnPlugin' )
//
// Documentation about available bundled plugins can be found
// at https : // github . com / phan / phan / tree / v5 / . phan / plugins
//
// Alternately , you can pass in the full path to a PHP file
// with the plugin ' s implementation .
// ( e . g . 'vendor/phan/phan/.phan/plugins/AlwaysReturnPlugin.php' )
' plugins ' => [
// checks if a function , closure or method unconditionally returns .
// can also be written as 'vendor/phan/phan/.phan/plugins/AlwaysReturnPlugin.php'
' AlwaysReturnPlugin ' ,
' DollarDollarPlugin ' ,
' DuplicateArrayKeyPlugin ' ,
' DuplicateExpressionPlugin ' ,
' PregRegexCheckerPlugin ' ,
' PrintfCheckerPlugin ' ,
' SleepCheckerPlugin ' ,
// Checks for syntactically unreachable statements in
// the global scope or function bodies .
' UnreachableCodePlugin ' ,
' UseReturnValuePlugin ' ,
' EmptyStatementListPlugin ' ,
' LoopVariableReusePlugin ' ,
],
];
Jetez un œil à Création d’un fichier de configuration et renforcement progressif de l’analyse pour plus de détails.
L'exécution phan --help
affichera les informations d'utilisation et les options de ligne de commande.
Phan lit et comprend la plupart des annotations de type PHPDoc, y compris les types Union (comme int|MyClass|string|null
) et les types de tableaux génériques (comme int[]
ou string[]|MyClass[]
ou array<int,MyClass>
).
Jetez un œil à Annotation de votre code source et À propos des types d’union pour obtenir de l’aide pour commencer à définir les types dans votre code.
Phan prend en charge les annotations de style (int|string)[]
et les représente en interne sous la forme int[]|string[]
(les deux annotations sont traitées comme un tableau pouvant contenir des entiers et/ou des chaînes). Lorsque vous avez des tableaux de types mixtes, utilisez simplement array
.
Le code suivant présente les différentes annotations prises en charge.
/ * *
* @ return void
* /
function f () {}
/ * * @ deprecated * /
class C {
/ * * @ var int * /
const C = 42 ;
/ * * @ var string [] | null * /
public $ p = null ;
/ * *
* @ param int | null $ p
* @ return string [] | null
* /
public static function f ( $ p ) {
if ( is_null ( $ p )) {
return null ;
}
return array_map (
/ * * @ param int $ i * /
function ( $ i ) {
return " thing $ i " ;
},
range ( 0 , $ p )
);
}
}
Tout comme en PHP, n'importe quel type peut être annulé dans la déclaration de fonction, ce qui signifie également qu'une valeur nulle peut être transmise pour ce paramètre.
Phan vérifie le type de chaque élément des tableaux (y compris les clés et les valeurs). En termes pratiques, cela signifie que [$int1=>$int2,$int3=>$int4,$int5=>$str6]
est vu comme array<int,int|string>
, que Phan représente comme array<int,int>|array<int,string>
. [$strKey => new MyClass(), $strKey2 => $unknown]
sera représenté comme array<string,MyClass>|array<string,mixed>
.
[12,'myString']
seront représentés en interne sous forme de formes de tableau telles que array{0:12,1:'myString'}
Cet analyseur statique ne suit pas les inclusions et n'essaie pas de comprendre la magie du chargeur automatique. Il traite tous les fichiers que vous lui lancez comme une seule grande application. Pour le code encapsulé dans les classes, cela fonctionne bien. Pour le code exécuté dans la portée globale, cela devient un peu délicat car l'ordre est important. Si vous avez un index.php
comprenant un fichier qui définit un tas de variables globales et que vous essayez ensuite d'y accéder après l' include(...)
dans index.php
l'analyseur statique n'en saura rien.
En termes pratiques, cela signifie simplement que vous devez placer vos points d'entrée et tous les fichiers définissant des éléments dans la portée globale en haut de votre liste de fichiers. Si vous avez un config.php
qui définit les variables globales dont tout le reste a besoin, alors vous devez le mettre en premier dans la liste suivi de vos différents points d'entrée, puis de tous vos fichiers de bibliothèque contenant vos classes.
Jetez un œil au Guide du développeur de Phan pour obtenir de l'aide pour commencer à pirater Phan.
Lorsque vous rencontrez un problème, prenez le temps de créer un petit extrait de code reproduisant le bug. Et une fois que vous avez fait cela, corrigez-le. Transformez ensuite votre extrait de code en test et ajoutez-le aux tests puis ./test
et envoyez un PR avec votre correctif et votre test. Vous pouvez également ouvrir un problème avec des détails.
Pour exécuter les tests unitaires de Phan, exécutez simplement ./test
.
Pour exécuter tous les tests unitaires et tests d'intégration de Phan, exécutez ./tests/run_all_tests.sh
Nous nous engageons à favoriser une communauté accueillante. Tout participant et contributeur est tenu de respecter notre code de conduite.
Cela nécessite une version à jour de Firefox/Chrome et au moins 4 Go de RAM libre. (il s'agit d'un téléchargement de 15 Mo)
Exécutez Phan entièrement dans votre navigateur.