Ini salah satu kesalahan deploy paling memalukan sekaligus paling mudah dilakukan. Saya sedang merapikan functions.php sebuah situs WordPress berlalu-lintas tinggi yang saya kelola, memecah kode jadi file-file inc/*.php yang lebih rapi. Saya tambahkan satu baris:
require_once get_template_directory() . '/inc/social-share.php';Saya upload functions.php lewat WP File Manager (plugin yang saya pakai untuk deploy). Lalu situsnya mati total. wp-admin menampilkan:
There has been a critical error on this website.
Dan inilah bagian yang bikin keringat dingin: WP File Manager itu sendiri hidup di dalam wp-admin. Karena fatal error terjadi di setiap request — termasuk admin — saya kehilangan tool yang seharusnya saya pakai untuk memperbaikinya. Channel recovery-nya ikut mati bersama situsnya.
Akar masalah: functions.php dimuat di SETIAP request
Penyebabnya sepele: saya upload functions.php yang me-require_once file inc/social-share.php — tapi file barunya belum saya upload. Target require_once tidak ada, PHP melempar fatal error.
functions.php bukan file biasa. Ia dimuat WordPress di setiap request, termasuk dashboard admin. Jadi require_once yang menunjuk ke file yang tidak ada akan mematikan seluruh situs sekaligus tool yang akan Anda pakai untuk memperbaikinya. Ini bukan error yang terbatas di frontend; ia menyentuh segalanya.
Pencegahan #1: urutan upload itu penting
Aturannya sederhana tapi sering dilanggar saat buru-buru: upload dependensi sebelum pemanggilnya.
- Upload file
inc/*.phpyang baru dulu. - Baru upload
functions.phpyang me-require-nya.
Kalau bisa upload atomik (rsync, git deploy, zip yang di-extract sekaligus), pakai itu supaya tidak ada jendela waktu di mana functions.php baru ada tapi dependensinya belum.
Pencegahan #2: bungkus include secara defensif
Saat deploy via file manager — di mana upload tidak atomik — jangan pernah percaya file dependensi pasti sudah ada. Bungkus tiap include dengan file_exists():
if ( file_exists( $f = get_template_directory() . '/inc/social-share.php' ) ) {
require_once $f;
}Dengan ini, file yang hilang akan degrade dengan anggun — fitur social share-nya tidak muncul, tapi situs tetap hidup dan wp-admin tetap bisa diakses. Jauh lebih baik daripada layar putih "critical error".
Recovery saat sudah terlanjur terkunci
Kalau situs sudah mati dan wp-admin tidak bisa diakses, lupakan semua plugin — Anda tidak bisa membuka satu pun. Anda butuh akses file di luar WordPress:
- Login ke SFTP atau cPanel File Manager (yang ini di luar WordPress, jadi tetap hidup).
- Lakukan salah satu:
- Upload file yang hilang (
inc/social-share.php) — fatal-nya langsung sembuh; atau - Komentari / hapus baris
require_oncedarifunctions.phpagar tidak lagi mencari file yang tidak ada.
- Upload file yang hilang (
- Reload situs. Begitu fatal-nya hilang, wp-admin (dan WP File Manager) hidup lagi.
Varian yang lebih ringan dari kelas bug yang sama
Bug ini punya sepupu yang gejalanya beda tapi penyebabnya identik — urutan deploy yang terbalik. Saya menambahkan fungsi baru ke sebuah file inc yang sudah ada, lalu meng-upload pemanggilnya duluan sebelum file inc yang sudah diperbarui:
Fatal error: Call to undefined function my_new_social_share()
Fungsinya belum ada karena file yang mendefinisikannya belum ter-upload. Sama persis polanya: pemanggil mendahului definisi → fatal.
Checklist deploy untuk apa pun yang dimuat di setiap request
- Upload dependensi sebelum pemanggil — file
inc/*.phpbaru dulu,functions.phpbelakangan. - Kalau memungkinkan, deploy atomik (git/rsync/zip) untuk menghilangkan jendela waktu yang berbahaya.
- Bungkus include dengan
file_exists()saat deploy lewat file manager — file hilang harus degrade, bukan fatal. - Jangan andalkan tool yang hidup di dalam wp-admin sebagai satu-satunya channel recovery — siapkan akses SFTP/cPanel.
- Saat terkunci: upload file yang hilang atau hapus baris require lewat SFTP — bukan lewat plugin apa pun.
Pelajarannya: untuk apa pun yang dimuat di setiap request, urutan deploy itu penting. Upload dependensi sebelum pemanggilnya, dan jaga include Anda dengan file_exists() setiap kali Anda men-deploy lewat tool yang hidup di dalam situs yang sedang Anda ubah.
