Phan adalah penganalisa statis untuk PHP yang lebih memilih untuk meminimalkan positif palsu. Phan mencoba membuktikan kesalahan, bukan kebenaran.
Phan mencari masalah umum dan akan memverifikasi kompatibilitas tipe pada berbagai operasi ketika informasi tipe tersedia atau dapat disimpulkan. Phan memiliki pemahaman yang baik (tetapi tidak komprehensif) tentang kontrol aliran dan dapat melacak nilai dalam beberapa kasus penggunaan (misalnya array, integer, dan string).
Cara termudah untuk menggunakan Phan adalah melalui Komposer.
composer require phan/phan
Dengan Phan terinstal, Anda dapat membuat file .phan/config.php
di proyek Anda untuk memberi tahu Phan cara menganalisis kode sumber Anda. Setelah dikonfigurasi, Anda dapat menjalankannya melalui ./vendor/bin/phan
.
Phan 5 bergantung pada PHP 7.2+ dengan ekstensi php-ast (lebih disukai 1.1.1+) dan mendukung analisis sintaksis PHP versi 7.0-8.2. Petunjuk instalasi php-ast dapat ditemukan di sini. (Phan dapat digunakan tanpa php-ast dengan menggunakan opsi CLI --allow-polyfill-parser
, tetapi ada sedikit perbedaan dalam penguraian komentar dokumen)
Wiki memiliki lebih banyak informasi tentang penggunaan Phan.
Phan mampu melakukan jenis analisis berikut:
object
, void
, iterable
, ?T
, [$x] = ...;
, offset string negatif, beberapa tangkapan pengecualian, dll.)--dead-code-detection
)--unused-variable-detection
)--redundant-condition-detection
)use
yang tidak digunakan. Masalah ini dan beberapa jenis masalah lainnya dapat diperbaiki secara otomatis dengan --automatic-fix
.@template
).int[]
, UserObject[]
, array<int,UserObject>
, dll.array{key:string,otherKey:?stdClass}
, dll. (secara internal dan dalam tag PHPDoc) Ini juga mendukung indikasi bahwa bidang bentuk array bersifat opsional melalui array{requiredKey:string,optionalKey?:string}
(berguna untuk @param
)@deprecated
untuk penghentian kelas, metode, dan fungsi@internal
untuk elemen (seperti konstanta, fungsi, kelas, konstanta kelas, properti, atau metode) sebagai internal pada paket yang mendefinisikannya.@suppress <ISSUE_TYPE>
untuk mengatasi masalah.@property <union_type> <variable_name>
)@method <union_type> <method_name>(<union_type> <param1_name>)
)class_alias
(eksperimental, dinonaktifkan secara default)@phan-closure-scope
(contoh)array_map
, array_filter
, dan fungsi array internal lainnya.pcntl
)Lihat Jenis Masalah Phan untuk deskripsi dan contoh semua masalah yang dapat dideteksi oleh Phan. Lihatlah PhanIssue untuk melihat definisi setiap jenis kesalahan.
Lihatlah Tutorial Menganalisis Basis Kode Ceroboh yang Besar untuk mendapatkan gambaran seperti apa proses melakukan analisis berkelanjutan bagi Anda.
Phan dapat digunakan dari berbagai editor dan IDE untuk pemeriksaan kesalahannya, dukungan "pergi ke definisi", dll. melalui Protokol Server Bahasa. Editor dan alat juga dapat meminta analisis file individual dalam suatu proyek menggunakan Mode Daemon yang lebih sederhana.
Lihat direktori tes untuk beberapa contoh berbagai pemeriksaan.
Phan tidak sempurna dan tidak boleh digunakan untuk membuktikan bahwa sistem panduan roket berbasis PHP Anda bebas dari cacat.
Fitur analisis tambahan telah disediakan oleh plugin.
{ throw new Exception("Message"); return $value; }
)*printf()
terhadap argumen yang diberikan (serta memeriksa kesalahan umum)preg_*()
valid@suppress
yang tidak lagi diperlukan.Contoh: Plugin Phan untuk analisis diri.
Setelah menginstal Phan, Phan perlu dikonfigurasi dengan detail tentang di mana menemukan kode untuk dianalisis dan cara menganalisisnya. Cara termudah untuk memberitahu Phan di mana menemukan kode sumber adalah dengan membuat file .phan/config.php
. File .phan/config.php
sederhana mungkin terlihat seperti berikut.
<?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 ' ,
],
];
Lihat Membuat File Konfigurasi dan Memperkuat Analisis Secara Bertahap untuk lebih jelasnya.
Menjalankan phan --help
akan menampilkan informasi penggunaan dan opsi baris perintah.
Phan membaca dan memahami sebagian besar anotasi tipe PHPDoc termasuk Tipe Union (seperti int|MyClass|string|null
) dan tipe array generik (seperti int[]
atau string[]|MyClass[]
atau array<int,MyClass>
).
Lihat Menganotasi Kode Sumber Anda dan Tentang Tipe Gabungan untuk mendapatkan bantuan dalam memulai mendefinisikan tipe dalam kode Anda.
Phan mendukung anotasi gaya (int|string)[]
, dan merepresentasikannya secara internal sebagai int[]|string[]
(Kedua anotasi diperlakukan seperti array yang mungkin memiliki bilangan bulat dan/atau string). Jika Anda memiliki array dengan tipe campuran, gunakan saja array
.
Kode berikut menunjukkan berbagai anotasi yang didukung.
/ * *
* @ 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 )
);
}
}
Sama seperti di PHP, tipe apa pun dapat di-null dalam deklarasi fungsi yang juga berarti null boleh diteruskan untuk parameter tersebut.
Phan memeriksa tipe setiap elemen array (Termasuk kunci dan nilai). Dalam istilah praktis, ini berarti [$int1=>$int2,$int3=>$int4,$int5=>$str6]
dipandang sebagai array<int,int|string>
, yang direpresentasikan oleh Phan sebagai array<int,int>|array<int,string>
. [$strKey => new MyClass(), $strKey2 => $unknown]
akan direpresentasikan sebagai array<string,MyClass>|array<string,mixed>
.
[12,'myString']
akan direpresentasikan secara internal sebagai bentuk array seperti array{0:12,1:'myString'}
Penganalisis statis ini tidak melacak penyertaan atau mencoba mencari tahu keajaiban pemuat otomatis. Ini memperlakukan semua file yang Anda lemparkan sebagai satu aplikasi besar. Untuk kode yang dienkapsulasi dalam kelas, ini berfungsi dengan baik. Untuk kode yang berjalan dalam lingkup global, ini menjadi sedikit rumit karena urutan itu penting. Jika Anda memiliki index.php
yang menyertakan file yang menetapkan sekumpulan variabel global dan Anda kemudian mencoba mengakses variabel tersebut setelah include(...)
di index.php
penganalisis statis tidak akan mengetahui apa pun tentang ini.
Secara praktis, ini berarti Anda harus meletakkan titik masuk dan pengaturan file apa pun dalam lingkup global di bagian atas daftar file Anda. Jika Anda memiliki config.php
yang menetapkan variabel global yang dibutuhkan semua hal lainnya, maka Anda harus meletakkannya di urutan pertama diikuti dengan berbagai titik masuk Anda, lalu semua file perpustakaan yang berisi kelas Anda.
Lihatlah Panduan Pengembang untuk Phan untuk bantuan dalam memulai meretas Phan.
Saat Anda menemukan masalah, luangkan waktu untuk membuat cuplikan kode reproduksi kecil yang menggambarkan bug tersebut. Dan setelah Anda selesai melakukannya, perbaiki. Kemudian ubah cuplikan kode Anda menjadi pengujian dan tambahkan ke pengujian lalu ./test
dan kirimkan PR dengan perbaikan dan pengujian Anda. Alternatifnya, Anda dapat membuka Masalah dengan detailnya.
Untuk menjalankan pengujian unit Phan, jalankan saja ./test
.
Untuk menjalankan semua pengujian unit dan pengujian integrasi Phan, jalankan ./tests/run_all_tests.sh
Kami berkomitmen untuk membina komunitas yang ramah. Setiap peserta dan kontributor wajib mematuhi Kode Etik kami.
Ini memerlukan versi terbaru Firefox/Chrome dan setidaknya 4 GB RAM kosong. (ini adalah unduhan 15 MB)
Jalankan Phan sepenuhnya di browser Anda.