Phan ist ein statischer Analysator für PHP, der Fehlalarme minimiert. Phan versucht eher, Unrichtigkeit als Richtigkeit zu beweisen.
Phan sucht nach häufigen Problemen und überprüft die Typkompatibilität bei verschiedenen Vorgängen, wenn Typinformationen verfügbar sind oder abgeleitet werden können. Phan verfügt über ein gutes (aber nicht umfassendes) Verständnis der Flusskontrolle und kann Werte in einigen Anwendungsfällen verfolgen (z. B. Arrays, Ganzzahlen und Zeichenfolgen).
Der einfachste Weg, Phan zu nutzen, ist über Composer.
composer require phan/phan
Wenn Phan installiert ist, möchten Sie in Ihrem Projekt eine .phan/config.php
Datei erstellen, um Phan mitzuteilen, wie es Ihren Quellcode analysieren soll. Sobald es konfiguriert ist, können Sie es über ./vendor/bin/phan
ausführen.
Phan 5 basiert auf PHP 7.2+ mit der Erweiterung php-ast (1.1.1+ wird bevorzugt) und unterstützt die Analyse der PHP-Syntaxversion 7.0–8.2. Eine Installationsanleitung für php-ast finden Sie hier. (Phan kann ohne php-ast verwendet werden, indem die CLI-Option --allow-polyfill-parser
verwendet wird, es gibt jedoch geringfügige Unterschiede beim Parsen von Dokumentkommentaren.)
Das Wiki enthält weitere Informationen zur Verwendung von Phan.
Phan ist in der Lage, die folgenden Arten von Analysen durchzuführen:
object
, void
, iterable
, ?T
, [$x] = ...;
, negative String-Offsets, mehrere Ausnahme-Catches usw.)--dead-code-detection
)--unused-variable-detection
)--redundant-condition-detection
)use
. Diese und einige andere Problemtypen können mit --automatic-fix
automatisch behoben werden.@template
).int[]
, UserObject[]
, array<int,UserObject>
usw.array{key:string,otherKey:?stdClass}
usw. (intern und in PHPDoc-Tags). Dies unterstützt auch die Angabe, dass Felder einer Array-Form optional sind über array{requiredKey:string,optionalKey?:string}
(nützlich für @param
)@deprecated
-Annotation zum Verwerfen von Klassen, Methoden und Funktionen@internal
-Annotation für Elemente (z. B. eine Konstante, Funktion, Klasse, Klassenkonstante, Eigenschaft oder Methode) als intern für das Paket, in dem sie definiert ist.@suppress <ISSUE_TYPE>
-Annotationen zum Unterdrücken von Problemen.@property <union_type> <variable_name>
)@method <union_type> <method_name>(<union_type> <param1_name>)
)class_alias
Anmerkungen (experimentell, standardmäßig deaktiviert)@phan-closure-scope
(Beispiel)array_map
, array_filter
und andere interne Array-Funktionen übergeben werden.pcntl
)Beschreibungen und Beispiele aller Probleme, die von Phan erkannt werden können, finden Sie unter Phan-Problemtypen. Werfen Sie einen Blick auf PhanIssue, um die Definition jedes Fehlertyps zu sehen.
Werfen Sie einen Blick auf das Tutorial zum Analysieren einer großen schlampigen Codebasis, um einen Eindruck davon zu bekommen, wie der Prozess der fortlaufenden Analyse für Sie aussehen könnte.
Phan kann über das Language Server Protocol von verschiedenen Editoren und IDEs aus zur Fehlerprüfung, zur „Go-to-Definition“-Unterstützung usw. verwendet werden. Mit dem einfacheren Daemon-Modus können Redakteure und Tools auch die Analyse einzelner Dateien in einem Projekt anfordern.
Einige Beispiele für die verschiedenen Prüfungen finden Sie im Testverzeichnis.
Phan ist unvollständig und sollte nicht als Beweis dafür verwendet werden, dass Ihr PHP-basiertes Raketenleitsystem fehlerfrei ist.
Zusätzliche Analysefunktionen wurden durch Plugins bereitgestellt.
{ throw new Exception("Message"); return $value; }
)*printf()
Formatzeichenfolgen anhand der bereitgestellten Argumente prüfen (und auf häufige Fehler prüfen)preg_*()
übergebene PCRE-Regexes gültig sind@suppress
-Annotationen, die nicht mehr benötigt werden.Beispiel: Phans Plugins zur Selbstanalyse.
Nach der Installation von Phan muss Phan mit Details dazu konfiguriert werden, wo der zu analysierende Code zu finden ist und wie er analysiert werden soll. Der einfachste Weg, Phan mitzuteilen, wo der Quellcode zu finden ist, besteht darin, eine .phan/config.php
Datei zu erstellen. Eine einfache .phan/config.php
Datei könnte etwa wie folgt aussehen.
<?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 ' ,
],
];
Weitere Einzelheiten finden Sie unter Erstellen einer Konfigurationsdatei und Inkrementelle Stärkung der Analyse.
Wenn Sie phan --help
ausführen, werden Nutzungsinformationen und Befehlszeilenoptionen angezeigt.
Phan liest und versteht die meisten PHPDoc-Typanmerkungen, einschließlich Union-Typen (wie int|MyClass|string|null
) und generischen Array-Typen (wie int[]
oder string[]|MyClass[]
oder array<int,MyClass>
).
Werfen Sie einen Blick auf Annotieren Ihres Quellcodes und Informationen zu Union-Typen, um Hilfe beim Einstieg in die Definition von Typen in Ihrem Code zu erhalten.
Phan unterstützt Annotationen (int|string)[]
Stil und stellt sie intern als int[]|string[]
dar (Beide Annotationen werden wie Arrays behandelt, die ganze Zahlen und/oder Zeichenfolgen enthalten können). Wenn Sie Arrays mit gemischten Typen haben, verwenden Sie einfach array
.
Der folgende Code zeigt die verschiedenen unterstützten Anmerkungen.
/ * *
* @ 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 )
);
}
}
Genau wie in PHP kann jeder Typ in der Funktionsdeklaration auf Null gesetzt werden, was auch bedeutet, dass für diesen Parameter ein Nullwert übergeben werden darf.
Phan prüft den Typ jedes einzelnen Array-Elements (einschließlich Schlüssel und Werte). In der Praxis bedeutet dies, dass [$int1=>$int2,$int3=>$int4,$int5=>$str6]
als array<int,int|string>
angesehen wird, das Phan als array<int,int>|array<int,string>
darstellt array<int,int>|array<int,string>
. [$strKey => new MyClass(), $strKey2 => $unknown]
wird als array<string,MyClass>|array<string,mixed>
dargestellt.
[12,'myString']
werden intern als Array-Formen wie array{0:12,1:'myString'}
dargestellt. Dieser statische Analysator verfolgt keine Includes und versucht nicht, die Autoloader-Magie herauszufinden. Es behandelt alle Dateien, die Sie darauf werfen, als eine große Anwendung. Für in Klassen gekapselten Code funktioniert dies gut. Bei Code, der im globalen Bereich ausgeführt wird, wird es etwas knifflig, da die Reihenfolge wichtig ist. Wenn Sie eine index.php
haben, die eine Datei enthält, die eine Reihe globaler Variablen festlegt, und Sie dann versuchen, nach dem include(...)
in index.php
auf diese zuzugreifen, weiß der statische Analysator nichts darüber.
In der Praxis bedeutet dies einfach, dass Sie Ihre Einstiegspunkte und alle Dateien, die Dinge im globalen Bereich festlegen, ganz oben auf Ihrer Dateiliste platzieren sollten. Wenn Sie eine config.php
haben, die globale Variablen festlegt, die alles andere benötigt, dann sollten Sie diese zuerst in die Liste einfügen, gefolgt von Ihren verschiedenen Einstiegspunkten und dann allen Ihren Bibliotheksdateien, die Ihre Klassen enthalten.
Schauen Sie sich den Entwicklerleitfaden für Phan an, um Hilfe beim Einstieg in das Hacken von Phan zu erhalten.
Wenn Sie ein Problem finden, nehmen Sie sich bitte die Zeit, einen kleinen reproduzierenden Codeausschnitt zu erstellen, der den Fehler veranschaulicht. Und wenn Sie das getan haben, beheben Sie es. Verwandeln Sie dann Ihr Code-Snippet in einen Test und fügen Sie ihn zu „Tests“ und dann zu ./test
hinzu und senden Sie eine PR mit Ihrem Fix und Test. Alternativ können Sie ein Problem mit Details öffnen.
Um Phans Unit-Tests auszuführen, führen Sie einfach ./test
aus.
Um alle Komponententests und Integrationstests von Phan auszuführen, führen Sie ./tests/run_all_tests.sh
aus
Wir sind bestrebt, eine einladende Gemeinschaft zu fördern. Jeder Teilnehmer und Mitwirkende ist verpflichtet, unseren Verhaltenskodex einzuhalten.
Voraussetzung hierfür ist eine aktuelle Version von Firefox/Chrome und mindestens 4 GB freier RAM. (Dies ist ein 15 MB großer Download)
Führen Sie Phan vollständig in Ihrem Browser aus.