Larastan — analisis statis
Analisis statis menangkap kelas kesalahan yang tidak akan pernah ditemukan tes: method yang tidak ada, tipe yang tidak cocok, dan nilai null yang lolos ke tempat yang tidak mengharapkannya.
Intisari
- Larastan adalah PHPStan yang memahami keajaiban Laravel — facade, relasi, dan properti model.
- Sepuluh level. Mulai dari level yang lolos hari ini, lalu naikkan satu per satu.
- Naikkan level di dalam pipeline; menurunkannya harus jadi keputusan sadar, bukan kebiasaan.
- Baseline membekukan error yang sudah ada supaya kode baru tetap diperiksa ketat.
- Ia menemukan hal yang tes tidak bisa: cabang yang tidak pernah dijalankan tetap diperiksa.
Memasang
composer require --dev larastan/larastan
# phpstan.neon
includes:
- vendor/larastan/larastan/extension.neon
parameters:
level: 5
paths:
- app
- database
- routes
checkModelProperties: true
./vendor/bin/phpstan analyse
./vendor/bin/phpstan analyse --memory-limit=2G
./vendor/bin/phpstan analyse --generate-baseline
Apa yang ditemukan tiap level
| Level | Mulai menangkap |
|---|---|
| 0–1 | Kelas dan fungsi yang tidak ada, variabel yang belum didefinisikan |
| 2–3 | Method yang tidak ada pada objek; tipe kembalian yang salah |
| 4–5 | Kondisi yang selalu benar/salah; argumen bertipe salah — target awal yang realistis |
| 6 | Tipe yang hilang (parameter dan kembalian tanpa deklarasi) |
| 7–8 | Union type yang tidak lengkap; kemungkinan null |
| 9–10 | mixed diperlakukan sangat ketat |
Level 8 adalah lompatan yang paling berharga. Di situ PHPStan mulai menolak
$user->profil->nama ketika profil bisa null — persis penyebab
"Attempt to read property on null" yang biasanya baru ketahuan di produksi, pada baris yang jarang dilewati.
Perjalanan dari level 5 ke 8 memang butuh usaha, tapi kelas bug yang hilang setelahnya sangat besar.
Contoh temuan nyata
// Level 2 — method tidak ada (typo yang tidak akan ketahuan sampai baris itu jalan)
$artikel->terbitkanSekarang(); // yang benar: terbitkan()
// Level 5 — argumen bertipe salah
hitungPajak($request->input('jumlah')); // string dikirim ke parameter int
// Level 7 — cabang null tidak ditangani
return $artikel->penulis->nama; // penulis bisa null
// Level 8 — tipe kembalian tidak lengkap
public function cari(): Artikel // padahal bisa mengembalikan null
{
return Artikel::where('slug', $slug)->first();
}
Baseline: cara memulai di proyek yang sudah besar
./vendor/bin/phpstan analyse --generate-baseline
# phpstan.neon
includes:
- vendor/larastan/larastan/extension.neon
- phpstan-baseline.neon
parameters:
level: 8
Baseline mencatat setiap error yang ada hari ini dan mengabaikannya. Artinya kamu bisa langsung memasang level 8 untuk kode baru tanpa harus memperbaiki ribuan temuan lebih dulu. Utangnya dicicil: setiap kali menyentuh sebuah berkas, perbaiki temuannya dan hapus barisnya dari baseline.
Jangan pernah menaikkan baseline untuk membungkam error baru. Baseline adalah catatan utang, bukan tempat sampah. Kalau ia terus bertambah, ia berhenti bermakna. Aturan tim yang sehat: baseline hanya boleh menyusut.
Membantu analisis memahami kodemu
/**
* @return \Illuminate\Database\Eloquent\Collection<int, \App\Models\Artikel>
*/
public function terbaru(): Collection
{
return Artikel::latest()->take(10)->get();
}
/** @param array<int, string> $slug */
public function berdasarkanSlug(array $slug): Collection { /* ... */ }
Generic dalam PHPDoc adalah cara memberi tahu PHPStan isi sebuah koleksi. Tanpa itu, ia hanya tahu "ini
Collection" dan tidak bisa memeriksa apa pun tentang elemennya. Dengan itu, ->first()->judull
langsung tertangkap.
Di dalam pipeline
- name: Analisis statis
run: ./vendor/bin/phpstan analyse --error-format=github --no-progress
Analisis statis dan tes saling melengkapi, bukan menggantikan. PHPStan memeriksa setiap baris termasuk cabang yang tidak pernah dijalankan tes, tapi ia tidak tahu apa-apa tentang benar-tidaknya aturan bisnismu. Tes tahu aturan bisnis, tapi hanya untuk jalur yang benar-benar dijalankan. Kamu perlu keduanya.
Latihan: pasang Larastan dengan level 5, perbaiki temuannya, lalu naikkan ke level 8 dan buat baseline. Hitung berapa temuan di baseline itu — angka tersebut adalah peta utang teknis proyekmu, dan biasanya lebih jujur daripada perasaan siapa pun tentangnya.
Rangkuman ini sengaja dipangkas ke bagian yang dipakai di roadmap. Buka sumber aslinya saat kamu butuh detail lengkap atau referensi parameter.