Sejauh ini pesan error PHP selalu tampil apa adanya: begitu sebuah warning terjadi, PHP langsung mencetaknya di tengah output program. Perilaku seperti itu ideal saat kita mengembangkan kode karena setiap masalah langsung terlihat mata. Namun PHP sebenarnya memberi kita kendali penuh atas pelaporan error — jenis masalah apa saja yang dilaporkan, apakah pesannya ditampilkan ke layar, dan apakah pesannya disimpan sebagai catatan permanen. Setelah kita mengenal exception dan hierarkinya pada chapter-chapter sebelumnya, kini saatnya mundur selangkah dan mengatur mesin pelaporannya sendiri. Chapter ini membahas tiga pengaturan inti pelaporan error beserta operator @ untuk menekan pesan pada satu ekspresi tertentu.

Tiga Pengaturan Inti Pelaporan Error #

PHP memiliki tiga pengaturan yang bekerja sama membentuk kebijakan pelaporan error. error_reporting menentukan jenis masalah apa saja yang dilaporkan, mulai dari level ringan seperti E_WARNING hingga yang fatal seperti E_ERROR. display_errors menentukan apakah pesan yang dilaporkan itu dikirim ke output sehingga terlihat di layar. log_errors menentukan apakah pesan tersebut juga dicatat ke berkas log. Ketiganya berupa directive php.ini yang nilainya bisa kita baca dan ubah selama program berjalan.

Fungsi ini_get() membaca nilai sebuah directive, sedangkan error_reporting() tanpa argumen mengembalikan level yang sedang aktif:

php
<?php
echo "error_reporting: " . error_reporting() . "\n";
echo "display_errors: " . ini_get('display_errors') . "\n";
echo "log_errors: " . ini_get('log_errors') . "\n";

Output yang Dihasilkan:

text
error_reporting: 30719
display_errors: 1
log_errors: 0

Tiga baris output di atas memperlihatkan kondisi bawaan PHP 8.4 pada lingkungan latihan kita. Angka 30719 adalah nilai integer dari E_ALL — setiap bit pada bilangan ini mewakili satu level error yang aktif, dan pada PHP 8.4 bit E_STRICT sudah tidak termasuk lagi karena level tersebut dikategorikan usang. Nilai display_errors berupa string 1 artinya pesan error ditampilkan ke output, sedangkan log_errors bernilai 0 artinya pencatatan ke log dimatikan. Angka-angka ini bergantung pada konfigurasi server tempat PHP berjalan, jadi jangan dihafal — cukup pahami cara membacanya.

Perbandingan nilai yang lazim untuk kedua lingkungan kerja dirangkum pada tabel berikut:

DirectivePertanyaan yang dijawabPengembanganProduksi
error_reportingJenis error apa saja yang dilaporkan?E_ALLE_ALL
display_errorsPesan ditampilkan ke layar?OnOff
log_errorsPesan dicatat ke log?OpsionalOn

Perhatikan bahwa produksi tetap memakai E_ALL — kita ingin PHP melaporkan semua masalah, hanya saja laporannya dikirim ke log, bukan ke layar pengunjung. Alasan lengkap di balik kebijakan ini dibahas pada chapter production-error-handling .

Mengubah Level dengan error_reporting() #

Fungsi error_reporting() yang dipanggil dengan satu argumen mengganti level pelaporan dan mengembalikan level yang lama. Nilai kembalian ini penting saat kita ingin menurunkan level hanya untuk sebagian kode, lalu memulihkannya seperti semula. Level baru dibentuk dengan operator bitwise: & mengambil irisan dan ~ menegasikan sekumpulan bit dari konstanta level yang telah kita bahas pada chapter error-levels .

Mari kita lihat dulu perilaku bawaannya saat seluruh level aktif:

php
<?php
error_reporting(E_ALL);

echo $stok;
echo "Program tetap berjalan\n";

Output yang Dihasilkan:

text

Warning: Undefined variable $stok in /home/z/my-project/php-course/content/php/error-handling/error-reporting/.verify_tmp.php on line 4
Program tetap berjalan

Pesan warning muncul tercampur di output program karena display_errors aktif dan error_reporting(E_ALL) memastikan semua level dilaporkan. Meski begitu, baris Program tetap berjalan tetap tercetak — warning bersifat non-fatal; PHP hanya melaporkan kejadiannya lalu melanjutkan eksekusi ke baris berikutnya. Pembacaan $stok sendiri menghasilkan null, sehingga echo pertama tidak mencetak apa pun.

Sekarang kita matikan keluarga E_WARNING dan amati nilai kembaliannya:

php
<?php
$levelLama = error_reporting(E_ALL & ~E_WARNING);
echo "Level lama: $levelLama\n";
echo "Level baru: " . error_reporting() . "\n";

echo $stok;
echo "Warning kini tidak ditampilkan\n";

Output yang Dihasilkan:

text
Level lama: 30719
Level baru: 30717
Warning kini tidak ditampilkan

Mari kita telaah baris-baris kode di atas:

  1. Baris 2: error_reporting() dipanggil dengan E_ALL & ~E_WARNING (irisan E_ALL dengan negasi E_WARNING), sehingga level baru hanya kehilangan satu bit milik E_WARNING. Level lama yang dikembalikan — 30719 — tersimpan ke $levelLama.
  2. Baris 3-4: kedua nilai dicetak untuk memperlihatkan bahwa level berubah dari 30719 menjadi 30717, tepat selisih nilai bit E_WARNING yaitu 2.
  3. Baris 6: pembacaan $stok yang tadinya memicu warning kini tidak menghasilkan laporan apa pun karena jenisnya sudah dikeluarkan dari level aktif.

Mengubah Tampilan dengan display_errors #

Pengaturan display_errors menjawab pertanyaan yang berbeda: bukan “apakah error dilaporkan”, melainkan “di mana laporan itu ditampilkan”. Directive ini bisa ditulis di php.ini, tetapi juga bisa diubah kapan pun selama program berjalan melalui ini_set() karena termasuk kategori PHP_INI_ALL. Pola ini berguna ketika hanya sebagian alur program yang perlu tampilan bersih, misalnya saat menghasilkan output yang akan dibaca mesin lain:

php
<?php
error_reporting(E_ALL);
ini_set('display_errors', '0');

echo $stok;
echo "Warning tidak tampil di layar\n";

Output yang Dihasilkan:

text
Warning tidak tampil di layar

Meskipun error_reporting(E_ALL) tetap aktif, pesan warning tidak lagi muncul di output. Error-nya masih terjadi dan masih dianggap terjadi oleh PHP — hanya kanal penampilannya yang ditutup oleh ini_set('display_errors', '0'). Mengembalikan nilai ke '1' akan memunculkan pesan kembali pada warning berikutnya. Pada lingkungan produksi, kombinasi yang benar adalah display_errors dimatikan dan log_errors dinyalakan, sehingga kegagalan tidak tampil ke pengunjung tetapi tetap tercatat.

Konfigurasi yang setara dalam berkas php.ini terlihat seperti berikut:

ini
; php.ini untuk pengembangan
display_errors = On
display_startup_errors = On
error_reporting = E_ALL

; php.ini untuk produksi
display_errors = Off
log_errors = On
error_log = /var/log/aplikasi/php-error.log

PHP mendistribusikan dua berkas contoh ini sebagai php.ini-development dan php.ini-production. Directive display_startup_errors mengatur tampilan error yang terjadi bahkan sebelum program kita berjalan, yaitu saat PHP sendiri sedang dinyalakan — misalnya ekstensi gagal dimuat. Tujuan error_log pada blok produksi di atas akan kita praktikkan langsung pada chapter logging-errors .

Operator Penekanan @ #

Kadang satu ekspresi tertentu memang sudah kita sadari bisa gagal, dan laporannya justru mengganggu. PHP menyediakan operator penekan @ yang diletakkan di depan sebuah ekspresi untuk menekan laporan error dari ekspresi itu saja:

php
<?php
error_reporting(E_ALL);

$isi = @file_get_contents("berkas-tidak-ada.txt");
var_dump($isi);
echo "Program selesai tanpa pesan warning\n";

Output yang Dihasilkan:

text
bool(false)
Program selesai tanpa pesan warning

file_get_contents() mengembalikan false ketika berkas tidak ditemukan dan sekaligus memicu warning. Dengan @ di depan pemanggilannya, warning tersebut tidak ditampilkan sehingga output hanya berisi bool(false) dari var_dump() dan baris penutup. Tanggung jawab memeriksa kegagalan kini sepenuhnya berpindah ke kode kita — pada contoh ini kita membuktikan nilainya secara eksplisit dengan var_dump().

Ringkasan #

Kebijakan pelaporan error PHP dibentuk oleh tiga pengaturan yang saling melengkapi: error_reporting memilih jenis masalah yang dilaporkan, display_errors mengatur apakah laporan tampil di layar, dan log_errors mengatur pencatatannya ke berkas log. Ketiganya dapat dibaca dengan ini_get() dan diubah saat runtime dengan ini_set() maupun error_reporting(), sementara operator @ menekan laporan untuk satu ekspresi tertentu. Namun semua mekanisme ini masih bersifat pasif — PHP hanya menampilkan atau menyembunyikan laporannya. Kadang kita ingin bereaksi secara aktif: mencatat dengan format milik sendiri, atau mengubah warning menjadi exception yang bisa ditangkap try-catch. Untuk kebutuhan itu PHP menyediakan error handler kustom, topik chapter berikutnya.

Referensi #