PSR-1 dan PSR-12 adalah dua dokumen yang paling sering dimaksud orang ketika menyebut “coding standard PHP”. PSR-1 mendefinisikan aturan dasar yang harus dipatuhi agar kode dapat dibaca lintas tim: tag pembuka, penamaan class, method, dan konstanta. PSR-12 memperluas PSR-1 menjadi panduan gaya lengkap — indentasi, panjang baris, posisi kurung kurawal, hingga penempatan declare(strict_types=1). Pada chapter ini kita bedah aturan-aturan kuncinya dengan pasangan contoh sesuai dan tidak sesuai, lengkap dengan sejarah singkat mengapa PSR-12 menggantikan PSR-2.
Aturan Dasar PSR-1 #
PSR-1 memakai bahasa normatif standar RFC: MUST (harus) berarti kewajiban mutlak, SHOULD (sebaiknya) berarti rekomendasi kuat yang boleh menyimpul dengan alasan. Lima aturan dasarnya ringkas namun berdampak besar:
| Aturan PSR-1 | Ketentuan |
|---|---|
| Tag pembuka | Berkas PHP HARUS memakai <?php atau <?= |
| Simbol vs efek samping | Berkas SEBAIKNYA hanya mendeklarasikan symbol (class, function, konstanta) ATAU hanya menjalankan logika dengan efek samping — tidak keduanya |
| Nama class | PascalCase (StudlyCaps): InvoiceGenerator |
| Konstanta class | Huruf kapital semua dengan underscore: MAX_ITEM |
| Nama method | camelCase: generateInvoice() |
Aturan “simbol vs efek samping” sering dilewatkan padahal penting. Berkas yang mendeklarasikan class sebaiknya tidak sekaligus menjalankan echo, query database, atau menulis berkas di level atas. Pencampuran seperti itu membuat efek muncul hanya karena berkas di-include — misalnya oleh autoloader — dan memicu perilaku tak terduga yang sulit dilacak. Deklarasikan symbol di satu berkas; tarik logika bermuatan efek ke skrip masuk (entry point) terpisah.
Contoh Tidak Sesuai dan Sesuai PSR-1 #
Cara tercepat menanamkan aturan adalah membandingkan dua wujud kode. Blok berikut melanggar tiga aturan PSR-1 sekaligus tetapi tetap berjalan tanpa error — PHP tidak memaksa gaya, kesepakatanlah yang dilanggar:
<?php
class invoice_generator
{
const max_item = 10;
public function Generate_Invoice($items)
{
// isi method
}
}Tiga pelanggarannya: nama class invoice_generator memakai snake_case alih-alih PascalCase, konstanta max_item tidak ditulis kapital dengan underscore, dan method Generate_Invoice memakai gaya campuran alih-alih camelCase. Versi yang patuh terlihat seperti ini:
<?php
declare(strict_types=1);
class InvoiceGenerator
{
public const MAX_ITEM = 10;
final public function generateInvoice(array $items): string
{
$jumlahItem = count($items);
return "Invoice berisi {$jumlahItem} item";
}
}
$generator = new InvoiceGenerator();
echo $generator->generateInvoice(['Kopi', 'Teh', 'Gula']) . "\n";
echo 'Batas maksimal: ' . InvoiceGenerator::MAX_ITEM . "\n";Output yang Dihasilkan:
Invoice berisi 3 item
Batas maksimal: 10Mari kita bedah titik-titik kepatuhannya:
- Baris 3:
declare(strict_types=1);berdiri sebagai statement pertama berkas — syarat penempatan dari PSR-12 yang akan kita bahas sebentar lagi. - Baris 5: nama class
InvoiceGeneratormengikuti PascalCase sesuai PSR-1. - Baris 7: konstanta
MAX_ITEMkapital semua dengan underscore, dan diberi visibilitypublicsebagaimana diwajibkan PSR-12. - Baris 9: method
generateInvoice()camelCase; kata kuncifinalberada sebelum visibilitypublic, bukan sesudahnya. - Baris 11: variabel lokal
$jumlahItemcamelCase dan mengungkap isi tanpa perlu komentar.
PSR-12 sebagai Penerus PSR-2 #
Sejarahnya, gaya lengkap dulunya diatur PSR-2 yang diterima pada 2012. Seiring PHP menambahkan traits, sintaks pendek, dan fitur baru lainnya, PSR-2 kehilangan banyak kasus yang belum diaturnya, sehingga berstatus deprecated dan digantikan PSR-12 pada 2019 — dokumen yang memperluas PSR-1, bukan menggantikannya. PSR-12 juga ditulis agar dapat ditegakkan oleh alat seperti PHP_CodeSniffer dan PHP CS Fixer. Aturan-aturan kuncinya:
| Aturan PSR-12 | Ketentuan |
|---|---|
| Indentasi | Empat spasi, bukan tab |
| Panjang baris | Tidak ada hard limit; soft limit 120 karakter; disarankan tidak melebihi 80 |
| Satu class per berkas | Konsekuensi praktis PSR-4: nama class = nama berkas |
declare(strict_types=1) | Jika dipakai, HARUS menjadi statement pertama berkas |
Posisi final/abstract | Sebelum visibility: final public function |
Posisi static | Setelah visibility: public static function |
| Kata kunci | Huruf kecil semua: true, false, null |
| Visibility | WAJIB dideklarasikan pada semua property dan konstanta |
| Kurung kurawal | Class: buka di baris baru; struktur kontrol: buka di akhir baris yang sama |
Prefix _ | Tidak boleh dipakai untuk menandai method private/protected |
Sebagian besar aturan di atas berbunyi sepele, dan justru itu intinya: karena semuanya mekanis, formatter dapat memperbaikinya sekali jalan. Yang tidak bisa diserahkan ke mesin adalah kebiasaan menulis dalam pola yang benar sejak awal.
Gaya Struktur Kontrol dan Penempatan strict_types #
Struktur kontrol adalah bagian yang paling sering ditulis, jadi gayanya paling terasa. Pola PSR-12: satu spasi setelah keyword, kurung buka di akhir baris yang sama, } elseif (...) { menyatu dalam satu baris:
<?php
declare(strict_types=1);
$poin = 87;
if ($poin >= 85) {
$predikat = 'A';
} elseif ($poin >= 75) {
$predikat = 'B';
} else {
$predikat = 'C';
}
echo "Predikat: {$predikat}\n";Output yang Dihasilkan:
Predikat: APada blok tersebut, setiap cabang if/elseif/else membuka kurung kurawal di akhir baris kondisinya dan menutupnya pada baris tersendiri, sementara isi cabang terindentasi empat spasi. Kontras dengan class pada contoh sebelumnya yang kurung bukanya berada di baris baru setelah nama class — perbedaan yang disengaja oleh standar.
Sekarang penempatan declare(strict_types=1). Blok berikut sengaja menunjukkan penempatan yang salah — declare diletakkan setelah deklarasi namespace:
<?php
namespace App;
declare(strict_types=1);Jika Anda menjalankan berkas tersebut, PHP menghentikan eksekusi dengan pesan Fatal error: strict_types declaration must be the very first statement in the script di baris declare. Pesan ini adalah compile error — skrip tidak berjalan sama sekali, sebelum baris mana pun tereksekusi.
Ringkasan #
PSR-1 menjaga fondasi — tag pembuka, pemisahan deklarasi dari efek samping, dan penamaan class, konstanta, serta method. PSR-12 melengkapi dengan aturan gaya menyeluruh: indentasi empat spasi, soft limit 120 karakter, posisi kurung kurawal, urutan final sebelum visibility, hingga posisi declare(strict_types=1) sebagai statement pertama. Aturan yang mekanis sebaiknya diserahkan ke formatter agar energi tim habis untuk logika. Setelah bentuk kode terjaga, pertanyaan berikutnya adalah di mana berkas class seharusnya berada — jawabannya adalah standar PSR-4 pada chapter berikutnya.