Teori static analysis baru terasa nyata ketika analyzer pertama Anda melaporkan bug sungguhan di kode sendiri. Pada Chapter ini kita akan melakukannya dari nol: memasang PHPStan lewat Composer, menyiapkan sebuah berkas demo yang sengaja berisi beberapa bug tipe, menjalankan analisis, lalu membaca keluaran errornya baris demi baris. Semua perintah dan keluaran yang tampil di sini diambil dari eksekusi nyata dengan PHP 8.4 dan PHPStan 2.3 di lingkungan penulisan Course ini, sehingga Anda bisa mereplikasi langkah yang sama di proyek sendiri.
Memasang PHPStan #
PHPStan didistribusikan sebagai paket Composer. Dari direktori root proyek Anda, jalankan:
composer require --dev phpstan/phpstanComposer mengunduh paket beserta seluruh dependensinya ke direktori vendor/ dan mencatat versinya di composer.json. Baris penting dari keluarannya:
Using version ^2.3 for phpstan/phpstanBendera --dev menandakan PHPStan hanya dibutuhkan selama pengembangan, bukan di server produksi — penggunaan memori dan waktu deploy aplikasi tetap ramping. Setelah proses selesai, binary PHPStan tersedia di vendor/bin/phpstan. Panduan resmi pemasangan, termasuk alternatif berkas PHAR tanpa Composer, tersedia di dokumentasi PHPStan
.
Menyiapkan Berkas Demo #
Kita memakai sebuah class keranjang belanja sederhana. Simpan kode berikut sebagai src/keranjang.php di proyek Anda:
<?php
declare(strict_types=1);
final class Keranjang
{
/** @var array<string, int> */
private array $items = [];
/** @param array<string, int> $items */
public function __construct(array $items = [])
{
$this->items = $items;
}
public function tambah(string $nama, int $jumlah): void
{
$this->items[$nama] = $jumlah;
}
/** @return array<string, int> */
public function semua(): array
{
return $this->items;
}
public function total(): int
{
return array_sum($this->items);
}
}
$keranjang = new Keranjang(['Buku Tulis' => 3, 'Pensil' => 2]);
$keranjang->tambah('Penghapus', 'lima');
$keranjang->kosongkan();
echo 'Total: ' . strlen($keranjang) . "\n";Kode di atas lolos pemeriksaan sintaks dan terlihat wajar sekilas, tetapi tiga baris di bagian bawah menyimpan tiga bug berbeda:
- Baris
$keranjang->tambah('Penghapus', 'lima'): parameter keduatambah()bertipeint, sedangkan'lima'adalah string. - Baris
$keranjang->kosongkan(): methodkosongkan()tidak pernah didefinisikan di classKeranjang. - Baris
strlen($keranjang): functionstrlen()menerimastring, bukan objectKeranjang.
Jika dijalankan langsung, program ini berhenti dengan fatal error di pemanggilan kosongkan(). Tugas kita bukan menjalankannya, melainkan membiarkan PHPStan membacanya.
Analisis Pertama #
Tanpa konfigurasi apa pun, PHPStan bisa langsung dipanggil dengan menentukan direktori dan level analisis. Jalankan dari root proyek:
php vendor/bin/phpstan analyse src --level=5 --no-progressBendera --no-progress mematikan animasi bar progres agar keluaran bersih saat dicatat. Hasil eksekusinya:
------ -------------------------------------------------------------------
Line keranjang.php
------ -------------------------------------------------------------------
35 Parameter #2 $jumlah of method Keranjang::tambah() expects int,
string given.
🪪 argument.type
36 Call to an undefined method Keranjang::kosongkan().
🪪 method.notFound
38 Parameter #1 ($string) of function strlen expects string, Keranjang
given.
🪪 argument.type
------ -------------------------------------------------------------------
[ERROR] Found 3 errorsKetiga bug yang kita tanam ditemukan dalam sekali jalan, lengkap dengan nomor barisnya. Perhatikan juga exit code perintah ini: PHPStan mengembalikan 1 ketika ada error dan 0 ketika kode bersih — perilaku inilah yang nanti membuatnya cocok sebagai gerbang CI.
Membaca Pesan Error #
Setiap pesan PHPStan terdiri dari tiga bagian: lokasi, kalimat temuan, dan identifier aturan. Ambil pesan pertama sebagai contoh:
- Lokasi (
keranjang.phpbaris 35): berkas relatif terhadap direktori yang dianalisis, diikuti nomor baris persis tempat pelanggaran terjadi. - Kalimat temuan (
Parameter #2 $jumlah of method Keranjang::tambah() expects int, string given.): PHPStan menyebut posisi parameter secara bernomor (#2), nama parameter beserta pemiliknya, tipe yang diharapkan (int), dan tipe yang sebenarnya dikirim (string). Dari satu kalimat ini kita tahu persis harus memperbaiki argumen di baris 35, atau mengubah deklarasi parameter jika memang kontraknya salah. - Identifier (
argument.type): kode aturan yang dilanggar — berguna untuk mencari dokumentasi aturan, menonaktifkannya secara selektif, atau menyaringnya di baseline.
Pesan kedua (method.notFound) menunjukkan keluarga temuan berbeda: symbol yang tidak ada. Pesan ketiga menunjukkan bahwa pemeriksaan tipe argumen juga berlaku untuk function bawaan PHP seperti strlen() — PHPStan memahami ribuan signature internal. Identifier pada tiap temuan menjadi kosakata bersama antara Anda dan konfigurasi, sehingga referensi konfigurasi PHPStan
selalu menyebutnya.
Konfigurasi phpstan.neon #
Mengetik --level=5 pada setiap pemanggilan cepat menjadi merepotkan, dan angka itu sebaiknya memang disimpan di version control agar seluruh tim menganalisis dengan standar sama. Buat berkas phpstan.neon di root proyek:
parameters:
level: 5
paths:
- srcBerkas ini menyimpan dua keputusan: level ketatness analisis (kita bahas daftar lengkap level 0-10 pada Chapter Baseline dan Analysis Levels ) dan daftar direktori yang dianalisis. Sekarang perintahnya cukup:
php vendor/bin/phpstan analyse --no-progressKeluarannya:
Note: Using configuration file /tmp/phpstan-test/phpstan.neon.
------ -------------------------------------------------------------------
Line keranjang.php
------ -------------------------------------------------------------------
35 Parameter #2 $jumlah of method Keranjang::tambah() expects int,
string given.
🪪 argument.type
36 Call to an undefined method Keranjang::kosongkan().
🪪 method.notFound
38 Parameter #1 ($string) of function strlen expects string, Keranjang
given.
🪪 argument.type
------ -------------------------------------------------------------------
[ERROR] Found 3 errorsPHPStan otomatis menemukan phpstan.neon di direktori kerja dan mencantumkan berkas konfigurasi yang dipakai pada baris Note: — path lengkapnya akan mengikuti lokasi proyek di mesin Anda. Temuan yang muncul identik dengan pemanggilan manual karena parameter level dan paths kini hidup di berkas konfigurasi.
Mendaftarkan perintah panjang sebagai script Composer membuatnya semakin ringkas. Tambahkan entri berikut di composer.json:
{
"scripts": {
"stan": "phpstan analyse --memory-limit=1G"
}
}Sejak saat ini, composer stan dari root proyek menjalankan analisis dengan konfigurasi yang sama untuk semua anggota tim.
Ringkasan #
Dalam satu Chapter ini kita menjalankan siklus lengkap PHPStan: pasang lewat composer require --dev, analisis direktori src dengan --level=5, baca tabel temuan beserta identifier aturannya, lalu kunci standar ke dalam phpstan.neon supaya tim memakai level yang sama. Tiga bug demo — argumen salah tipe, method hantu, dan salah kirim ke function internal — semuanya tertangkap tanpa menjalankan program. Ekosistem PHP memiliki satu analyzer besar lainnya dengan pendekatan dan kekuatan berbeda; Chapter berikutnya
mengulang perjalanan yang sama dengan Psalm, lalu membandingkan keduanya.