Programming Tutorial PHP Laravel Code Quality 27 July 2025

Code Quality Check dengan PHPStan di Laravel (Panduan Lengkap untuk Pemula)

Code Quality Check dengan PHPStan di Laravel (Panduan Lengkap untuk Pemula)
Bagikan:

Pernah nggak sih kamu ngerasa deg-degan setiap kali deploy aplikasi Laravel ke server? Takut ada bug yang nggak ketahuan, atau error yang baru muncul pas sudah live? Nah, di dunia programming, menjaga kualitas kode itu penting banget—dan salah satu cara paling efektif adalah dengan menggunakan static analysis tool seperti PHPStan.

Di artikel ini, kita bakal bahas tuntas cara meningkatkan kualitas kode Laravel dengan PHPStan. Mulai dari instalasi, setup, sampai tips mengatasi error yang sering bikin pusing. Tenang, semua dijelaskan step-by-step, pakai bahasa santai dan analogi sehari-hari. Yuk, mulai perjalanan jadi developer yang lebih percaya diri!

Kenalan dengan PHPStan: Si Detektif Kode PHP

Bayangin kamu punya “detektif” yang selalu siap memeriksa kode PHP-mu, mencari bug, typo, atau potensi masalah—bahkan sebelum aplikasi dijalankan. Itulah peran PHPStan! Tool ini melakukan static analysis, artinya dia menganalisis kode tanpa perlu menjalankan aplikasi. Cocok banget buat kamu yang pengen kode lebih aman dan minim error.

Kenapa Harus Pakai PHPStan?

  • Mendeteksi bug lebih awal: Error bisa ditemukan sebelum aplikasi dijalankan.
  • Meningkatkan kepercayaan diri: Deploy ke production jadi lebih tenang.
  • Membantu belajar best practices: PHPStan sering kasih saran perbaikan kode.
  • Bisa diintegrasikan ke CI/CD: Otomatis scan setiap push ke repo.

Persiapan: Tools yang Dibutuhkan

Sebelum mulai, pastikan kamu sudah punya:

  • Laravel (versi terbaru, misal 10.x)
  • Composer (untuk install dependency PHP)
  • PHPStan dan Larastan (plugin PHPStan khusus Laravel)
  • jq (untuk parsing output JSON PHPStan)

Cara Install PHPStan & Larastan

composer require --dev phpstan/phpstan larastan/larastan

Setelah itu, buat file konfigurasi di root project:

touch phpstan.neon.dist

Isi dengan konfigurasi dasar berikut (bisa disesuaikan):

includes:
    - vendor/larastan/larastan/extension.neon
parameters:
    treatPhpDocTypesAsCertain: false
    paths:
        - app/
        - config/
        - database/
        - routes/
        - support/
    level: 4
    excludePaths:
        - bin/
        - node_modules/
        - stubs/
        - vendor/
        - tests/
        - resources/

Tips: Level 4 cocok untuk pemula, tapi kamu bisa naikkan ke level 6 atau 8 kalau sudah lebih percaya diri. Semakin tinggi level, semakin ketat aturannya.

Install jq

Ubuntu/Debian:

sudo apt-get install jq

macOS:

brew install jq

Windows: Download dari situs resmi jq.

Struktur Folder yang Direkomendasikan

project-root/
├── .phpstan/           # hasil scan PHPStan
├── app/
├── config/
├── database/
├── routes/
├── support/
├── phpstan.neon.dist   # config PHPStan
├── bin/
│   └── phpstan         # custom bash script
└── vendor/

Membuat Script Otomatisasi PHPStan

Agar hasil scan lebih mudah dibaca, kita bisa bikin script Bash untuk parsing output PHPStan dan mengelompokkan error berdasarkan jenisnya. Berikut contoh script yang bisa kamu pakai di bin/phpstan:

#!/usr/bin/env bash

clear
echo "Running PHPStan..."
vendor/bin/phpstan --error-format=json > .phpstan/scan-result.json
jq . .phpstan/scan-result.json > .phpstan/scan-result.pretty.json && mv .phpstan/scan-result.pretty.json .phpstan/scan-result.json
input_file=".phpstan/scan-result.json"
output_dir=".phpstan"
if [[ ! -f "$input_file" ]]; then
  echo "❌ File $input_file not found."
  exit 1
fi
find "$output_dir" -type f -name '*.txt' -delete
if ! jq -e '.files != null and (.files | length > 0)' "$input_file" >/dev/null; then
  echo "ℹ️ No issues found or invalid PHPStan JSON output."
  exit 0
fi
mkdir -p "$output_dir"
echo "📂 Output directory ready: $output_dir"
echo "📄 Reading from: $input_file"
jq -r '
  .files as $files |
  $files | to_entries[] |
  .key as $file |
  .value.messages[] |
  [
    .identifier,
    $file,
    (.line | tostring),
    .message,
    (if (.tip != null and (.tip | type) == "string") then .tip else "" end),
    (if (.ignorable == true) then "Yes" else "No" end)
  ] | @tsv
' "$input_file" |
while IFS=$'\t' read -r identifier file line message tip ignorable; do
  output_file="${output_dir}/${identifier}.txt"
  {
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    echo "📂 File       : $file"
    echo "🔢 Line       : $line"
    echo "💬 Message    : $message"
    [[ -n "$tip" ]] && echo "💡 Tip        : $tip"
    echo "✅ Ignorable  : $ignorable"
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    echo ""
  } >> "$output_file"
done
echo "✅ PHPStan scan identifiers outputted into individual files."
# Generate summary
summary_file="${output_dir}/summary.txt"
label_width=42
total_issues=0
total_identifiers=0
temp_summary_data=$(mktemp)
for file in "$output_dir"/*.txt; do
  [[ "$file" == "$summary_file" ]] && continue
  identifier=$(basename "$file" .txt)
  count=$(grep -c "📂 File" "$file")
  printf -- "- %-${label_width}s : %4d\n" "$identifier" "$count" >> "$temp_summary_data"
  total_issues=$((total_issues + count))
  total_identifiers=$((total_identifiers + 1))
done
{
  echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
  echo "🔎 PHPStan Scan Summary"
  echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
  printf -- "- %-${label_width}s  : %4d\n" "Unique Identifiers" "$total_identifiers"
  printf -- "- %-${label_width}s : %4d\n" "Issues Found" "$total_issues"
  echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
  echo ""
  echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
  echo "📋 Issues by Identifier:"
  echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
  sort "$temp_summary_data"
  echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
} > "$summary_file"
echo "📊 Summary written to $summary_file"
rm -f "$temp_summary_data"

Catatan: Script ini akan menghasilkan file summary dan log error yang rapi di folder .phpstan/. Sangat membantu untuk review bareng tim atau debugging harian.

Menjalankan PHPStan

Cukup jalankan perintah berikut di terminal:

bin/phpstan

Hasilnya:

  • .phpstan/summary.txt — Ringkasan error berdasarkan kategori
  • .phpstan/*.txt — Detail error per kategori

Contoh Error & Cara Memperbaikinya

Misal kamu dapat error seperti ini:

📂 File       : app/Models/ApplicantProgramme.php
🔢 Line       : 10
💬 Message    : Access to an undefined property App\Models\ApplicantProgramme::$name.
💡 Tip        : Learn more: https://phpstan.org/blog/solving-phpstan-access-to-undefined-property
✅ Ignorable  : Yes

Cara Fix

Tambahkan PHPDoc property di model:

/**
 * @property string $name
 */
class ApplicantProgramme extends Model
{
    protected $table = 'applicant_programmes';
}

Atau, di PHP versi terbaru, sebaiknya deklarasikan property secara eksplisit:

class ApplicantProgramme extends Model
{
    protected $table = 'applicant_programmes';
    private string $name;
}

Referensi: Solving PHPStan Access to Undefined Property

Tips & Best Practice Menggunakan PHPStan

  • Selalu update ke versi terbaru: Gunakan versi terbaru PHPStan dan Larastan untuk fitur dan rule paling up-to-date.
  • Gunakan level bertahap: Mulai dari level 4, naikkan perlahan sesuai kesiapan project.
  • Integrasi di CI/CD: Tambahkan PHPStan di pipeline agar error terdeteksi otomatis.
  • Manfaatkan fitur bleeding edge: Tambahkan di config untuk rule experimental:
includes:
    - vendor/phpstan/phpstan/conf/bleedingEdge.neon
  • Cek versi PHP: Pastikan phpVersion di config sesuai target project (misal PHP 8.3):
parameters:
    phpVersion: 80300 # PHP 8.3.0
  • Gunakan baseline: Untuk project lama, generate baseline agar error lama tidak mengganggu development baru:
vendor/bin/phpstan analyse --generate-baseline
  • Cek environment: Untuk diagnosa, gunakan:
vendor/bin/phpstan diagnose

Integrasi dengan Laravel Pint

Laravel Pint adalah code style fixer otomatis. Tapi, beberapa rule Pint bisa menghapus PHPDoc yang dibutuhkan Larastan. Solusinya, matikan rule PHPDoc di pint.json:

{
    "preset": "laravel",
    "rules": {
        "no_superfluous_phpdoc_tags": false,
        "no_empty_phpdoc": false,
        "phpdoc_no_empty_return": false,
        "phpdoc_no_useless_inheritdoc": false,
        "phpdoc_trim": false,
        "phpdoc_trim_consecutive_blank_line_separation": false,
        "general_phpdoc_annotation_remove": false,
        "phpdoc_annotation_without_dot": false,
        "phpdoc_summary": false,
        "phpdoc_separation": false,
        "phpdoc_single_line_var_spacing": false,
        "phpdoc_to_comment": false,
        "phpdoc_tag_type": false,
        "phpdoc_var_without_name": false,
        "phpdoc_align": false,
        "phpdoc_indent": false,
        "phpdoc_inline_tag_normalizer": false,
        "phpdoc_no_alias_tag": false,
        "phpdoc_no_package": false,
        "phpdoc_scalar": false,
        "phpdoc_types": false,
        "phpdoc_types_order": false,
        "phpdoc_var_annotation_correct_order": false
    },
    "exclude": [
        "vendor",
        "node_modules",
        "storage",
        "bootstrap/cache"
    ]
}

Referensi: PHPStan Official Docs, Larastan, Laravel Pint

Menggunakan AI untuk Memperbaiki Error PHPStan

Setelah menjalankan script dan mendapatkan summary error, kamu bisa copy-paste error ke ChatGPT atau Copilot. Sertakan file, line, dan potongan kode terkait. Contoh prompt:

Saya pakai Laravel dan dapat error PHPStan:

Access to an undefined property App\Models\ApplicantProgramme::$name.

Berikut model saya:

class ApplicantProgramme extends Model
{
    protected $table = 'applicant_programmes';
}

Bagaimana cara fix-nya?

AI biasanya akan menyarankan menambah PHPDoc atau deklarasi property seperti contoh di atas.

Troubleshooting Error Umum

  • property.notFound: Tambahkan PHPDoc atau deklarasi property di model.
  • callToUndefinedMethod: Pastikan method memang ada di class/trait terkait.
  • type mismatch: Cek tipe data di PHPDoc dan implementasi kode.
  • symbol not found: Pastikan autoloading dan namespace sudah benar.

Langkah Selanjutnya

  • Coba naikkan level PHPStan secara bertahap.
  • Integrasikan ke CI/CD pipeline.
  • Review hasil scan bareng tim.
  • Eksplorasi fitur advanced seperti custom rule dan extension.

Penutup: Kode Bersih, Hati Tenang

Dengan PHPStan, kamu nggak cuma dapat kode yang lebih bersih, tapi juga rasa percaya diri setiap kali deploy. Jangan ragu untuk eksperimen, tanya AI, dan terus belajar. Ingat, semua developer hebat juga pernah jadi pemula. Semangat, ya!


Referensi Lanjutan: