Sabah bir e-posta geliyor: "Sitenizde teknik bir sorun oluştu." Adrese giriyorsunuz, ekran bomboş ya da tek satırlık bir "Bu sitede kritik bir hata oluştu" yazısı var. Dün gece iki eklenti güncellendi, tema da bir minör sürüm aldı. Hangisi kırdı? Ekranda hiçbir ipucu yok, çünkü WordPress hatayı bilinçli olarak sizden de ziyaretçiden de saklıyor.
Bu, WordPress'in varsayılan davranışıdır ve doğru bir davranıştır: canlı bir sitede PHP hatasının ekrana basılması, sunucu dosya yollarından veritabanı tablo öneklerine kadar saldırganın işine yarayacak bilgileri açığa çıkarır. Ama sorunu çözmek için o hatanın metnini görmeniz gerekir. Çözüm, hata raporlamayı açıp çıktıyı ekrana değil dosyaya yönlendirmektir.
Bu yazıda wp-config.php içindeki üç sabiti doğru kombinasyonla kurmayı, log dosyasını web'den indirilemeyecek bir yere taşımayı, debug.log içindeki bir satırdan hangi eklentinin hangi dosyasında ne olduğunu okumayı ve — en çok unutulan adım — iş bitince her şeyi kapatmayı ele alacağız.
WP_DEBUG Tam Olarak Neyi Açar?#
WP_DEBUG, WordPress'in çekirdeğinde wp-includes/load.php içindeki wp_debug_mode() fonksiyonunu tetikleyen bir sabittir. true yapıldığında iki şey olur:
- PHP'nin hata seviyesi
E_ALL'a çekilir. Yani sadece ölümcül hatalar değil, uyarılar (Warning), bildirimler (Notice) ve kullanımdan kaldırma duyuruları (Deprecated) da raporlanır. - WordPress'in kendi iç uyarıları devreye girer — örneğin bir eklentinin artık desteklenmeyen bir fonksiyonu çağırması
_doing_it_wrong()mesajı üretir.
Varsayılan değeri false'tur ve yeni kurulan her sitede wp-config.php içinde şu satırla gelir:
define( 'WP_DEBUG', false );
Tek başına true yapmak yeterli değil, hatta tehlikelidir: WP_DEBUG açıkken WP_DEBUG_DISPLAY tanımlanmamışsa WordPress hataları ekrana basar. PHP 8.x ile birlikte pek çok eski eklenti bir sürü Deprecated uyarısı ürettiği için, canlı sitede bunu yapmanız hâlinde ziyaretçiler ana sayfanın tepesinde sarı sarı uyarı blokları görür — ve o blokların içinde /home/kullanici/public_html/... şeklinde tam dosya yolunuz yazar.
Canlı Sitede Güvenli Kombinasyon: Üç Sabit Birlikte Çalışır#
Doğru kurulum tek bir sabit değil, üçünün belirli bir kombinasyonudur:
| Sabit | Değer | Etkisi |
|---|---|---|
WP_DEBUG | true | Hata raporlamayı E_ALL seviyesine çeker |
WP_DEBUG_DISPLAY | false | display_errors kapatılır, hiçbir şey ekrana basılmaz |
WP_DEBUG_LOG | true veya dosya yolu | log_errors açılır, çıktı dosyaya yazılır |
WP_DEBUG_DISPLAY sabitinin üç durumu olduğuna dikkat edin ve burada ince bir tuzak var: sabit hiç tanımlanmamışsa WordPress onu "açık" kabul eder. Yani "tanımlamazsam kapalı kalır" varsayımı yanlıştır; kapatmak istiyorsanız açıkça false yazmanız gerekir.
// Hata raporlamayı aç
define( 'WP_DEBUG', true );
// Ama ekrana HİÇBİR ŞEY basma (bu satır olmazsa ziyaretçi hatayı görür)
define( 'WP_DEBUG_DISPLAY', false );
// Çıktıyı dosyaya yaz
define( 'WP_DEBUG_LOG', true );
Bu üçlü ile WP_DEBUG_LOG değeri true olduğunda log dosyası wp-content/debug.log yoluna düşer. Dosya yoksa PHP ilk hata anında kendisi oluşturur; ayrıca touch ile boş dosya yaratmanıza gerek yoktur. Sadece wp-content dizininin web sunucusu kullanıcısı tarafından yazılabilir olması gerekir — izinler konusunda tereddüdünüz varsa WordPress dosya izinleri yazısı doğru değerleri veriyor.
Ekranda Hâlâ Uyarı Görüyorsanız#
Bazı paylaşımlı hosting ortamlarında display_errors sunucu tarafında zorlanmış olabilir ya da bir güvenlik eklentisi araya girer. WP_DEBUG_DISPLAY yetmezse wp-config.php içine aynı bölgeye şu iki satırı da ekleyin:
@ini_set( 'display_errors', 0 );
@ini_set( 'log_errors', 1 );
Bu Satırları wp-config.php'de Nereye Yazmalısınız?#
Yer önemlidir ve yanlış yere yazmak sabitleri tamamen etkisiz bırakır. wp-config.php dosyasının sonlarına doğru şöyle bir satır vardır:
/* That's all, stop editing! Happy publishing. */
Tüm hata ayıklama sabitleri bu satırdan önce tanımlanmalıdır. Çünkü hemen aşağıdaki require_once ABSPATH . 'wp-settings.php'; çağrısı WordPress'i başlatır ve wp_debug_mode() orada çalışır; ondan sonra tanımlanan bir sabit geç kalmış olur.
İkinci sık hata: dosyada zaten var olan define( 'WP_DEBUG', false ); satırını silmeden altına yenisini yazmak. PHP'de aynı sabiti ikinci kez tanımlamak Constant already defined uyarısı üretir ve ilk değer geçerli kalır; yani hata ayıklama açılmaz. Var olan satırı düzenleyin, kopyasını eklemeyin.
Düzenlemeye başlamadan önce dosyanın yedeğini alın. SSH erişiminiz varsa:
cd ~/public_html
cp wp-config.php wp-config.php.yedek-$(date +%F)
nano wp-config.php
debug.log Dosyasını Web'den Erişilemez Bir Yere Almak#
Varsayılan konum olan wp-content/debug.log işlevsel ama güvenli değildir: dosya doğrudan https://siteniz.com/wp-content/debug.log adresinden indirilebilir. İçinde ne var? Sunucu dizin yapınız, eklenti ve tema isimleri, bazen sorgu parçaları, kötü yazılmış bir eklenti hata mesajına değişken bastığında ise e-posta adresleri ya da API anahtarları. Bu, saldırgana bedava keşif raporu vermek demektir.
WordPress 5.1'den beri WP_DEBUG_LOG sabiti true yerine bir dosya yolu alabilir. En temiz çözüm budur — logu web kök dizininin (public_html) tamamen dışına çıkarın:
define( 'WP_DEBUG_LOG', '/home/kullanici/logs/wp-debug.log' );
Hedef dizinin var olması ve PHP'nin yazma izni olması gerekir; yoksa log sessizce hiçbir yere yazılmaz:
mkdir -p /home/kullanici/logs
chmod 750 /home/kullanici/logs
# Web sunucusu kullanıcısını öğrenmek için:
ps -eo user,comm | grep -E 'php-fpm|apache2|httpd|nginx' | sort -u
Yolu değiştiremiyorsanız (bazı yönetilen hosting paketleri kök dışına yazmaya izin vermez) en azından dosyayı web'den kapatın. Apache 2.4 için wp-content/.htaccess dosyasına:
<Files "debug.log">
Require all denied
</Files>
Nginx kullanıyorsanız sunucu bloğuna:
location ~* /debug\.log$ {
deny all;
access_log off;
}
Kuralı yazdıktan sonra tarayıcıdan dosyanın adresini açıp 403 aldığınızı gerçekten doğrulayın. .htaccess yazmak yetmez; Nginx'in .htaccess diye bir kavramı yoktur ve dosyayı tamamen yok sayar. Sunucunuzun hangisiyle çalıştığını bilmiyorsanız kural ekledikten sonraki testi atlamayın.
debug.log Satırı Nasıl Okunur?#
Log açıldıktan sonra sitede hatayı üreten sayfayı bir kez ziyaret edin, sonra dosyayı okuyun:
# Son 50 satır
tail -n 50 ~/logs/wp-debug.log
# Canlı izleme: siz sayfayı yenilerken satırlar aksın
tail -f ~/logs/wp-debug.log
# Sadece ölümcül hataları süz
grep -i "fatal error" ~/logs/wp-debug.log | tail -n 20
Tipik bir satır şöyle görünür:
[18-Aug-2026 06:41:22 UTC] PHP Fatal error: Uncaught Error: Call to undefined function wc_get_cart_url() in /home/kullanici/public_html/wp-content/plugins/ornek-kargo/includes/class-checkout.php:214
Stack trace:
#0 /home/kullanici/public_html/wp-includes/class-wp-hook.php(324): Ornek_Kargo_Checkout->render()
#1 /home/kullanici/public_html/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters()
Bu satırdan çıkarılacak dört bilgi var:
- Zaman damgası:
UTCyazdığına dikkat edin. WordPress PHP'nin varsayılan saat dilimini UTC'ye sabitler, bu yüzden log damgaları Türkiye saatinden 3 saat geridedir. "Saat 09:40'ta hata aldım ama logda öyle bir satır yok" diyorsanız 06:40 civarına bakın. - Seviye:
Fatal error,Warning,Noticeya daDeprecated. - Suçlu dosya:
wp-content/plugins/sonrasındaki ilk klasör adı eklentinin dizin adıdır — buradaornek-kargo.wp-content/themes/ile başlıyorsa sorumlu temadır. - Satır numarası:
:214. Kod tarafına bakabiliyorsanız doğrudan o satıra gidin.
Notice, Warning ve Fatal Error Farkı#
Log dosyası ilk açıldığında yüzlerce satır görüp paniklemeyin. Hepsi sorun değildir:
| Seviye | Site çalışır mı? | Ne anlama gelir | Ne yapmalı |
|---|---|---|---|
Deprecated | Evet | Eklenti, PHP'nin ileride kaldıracağı bir yapı kullanıyor | Not alın, eklenti güncellemesini bekleyin |
Notice | Evet | Tanımsız değişken/dizi anahtarı gibi özensiz kod | Genelde görmezden gelinir |
Warning | Evet ama eksik | Bir dosya bulunamadı, bir bağlantı kurulamadı | İncelenmeli, çoğu zaman gerçek bir kusur |
Fatal error | Hayır | PHP çalışmayı durdurdu | Beyaz ekranın/kritik hatanın sebebi budur |
Aradığınız şey neredeyse her zaman Fatal error satırıdır ve zaman damgası olayla eşleşen en son satırdır. Beyaz ekranla karşılaşıyorsanız WordPress beyaz ekran hatası yazısındaki adımlarla birlikte ilerleyin; "Bu sitede kritik bir hata oluştu" mesajı görüyorsanız kritik hata çözümü rehberi bu logu okumaya devam ediyor.
"Kritik Hata" Ekranı Gerçek Hatayı Gizliyorsa#
WordPress 5.2'den beri ölümcül hataları yakalayan bir kurtarma mekanizması var. Bir eklenti çöktüğünde WordPress sorunlu eklentiyi devre dışı bırakıp yöneticiye "kurtarma modu" bağlantısı içeren bir e-posta gönderir ve ziyaretçiye nötr bir mesaj gösterir. Bu iyi bir özelliktir ama hata ayıklarken önünüze geçebilir: gerçek Fatal error yerine hazır metni görürsünüz.
Tanıyı yaparken bu yakalayıcıyı geçici olarak kapatabilirsiniz:
define( 'WP_DISABLE_FATAL_ERROR_HANDLER', true );
Bu satır açıkken hata artık yakalanmaz; WP_DEBUG_DISPLAY kapalı olduğu için ekranda yine bir şey görünmez ama log dosyasına ham hatanın tamamı düşer. Teşhis biter bitmez bu sabiti kaldırın — aksi hâlde bir eklenti çöktüğünde WordPress'in otomatik kurtarma yeteneğini de kaybedersiniz.
Kurtarma modu e-postası gelmiyorsa sorun hata ayıklamada değil, e-posta gönderiminde olabilir; bu ayrı bir başlıktır.
Hangi Eklenti Suçlu? Logdan Doğrulamaya#
Log size bir dosya yolu verir ama bu, o eklentinin tek başına suçlu olduğu anlamına gelmez. Yukarıdaki örnekte ornek-kargo eklentisi wc_get_cart_url() çağırıyor — bu bir WooCommerce fonksiyonu. Yani asıl senaryo büyük ihtimalle "WooCommerce devre dışı kaldı ya da güncellendi, kargo eklentisi ona ayak uyduramadı" şeklindedir. Log, zincirin koptuğu yeri gösterir, zorunlu olarak zincirin hatalı halkasını değil.
Doğrulama için sırayla:
- Log satırındaki eklentiyi geçici olarak devre dışı bırakın. Panele giremiyorsanız FTP/dosya yöneticisiyle
wp-content/plugins/ornek-kargoklasörünüornek-kargo-kapaliolarak yeniden adlandırın; WordPress eklentiyi bulamayınca kendiliğinden pasife alır. - Site açılıyorsa suçluyu daralttınız. Klasör adını geri alıp eklentiyi tekrar aktif edin ve hatanın döndüğünü teyit edin — tek seferlik bir tesadüf olmadığından emin olun.
- Aynı hata birden çok eklentiyi işaret ediyorsa çakışma söz konusudur; eklenti çakışması yazısındaki ikili eleme yöntemi bu noktada devreye girer.
Bir eklentiyi klasör adı değiştirerek kapattıysanız, sorunu çözdükten sonra adı birebir eskisine döndürmeyi unutmayın. Eklenti ayarları çoğunlukla dosya yoluna değil veritabanına bağlıdır, ama bazı eklentiler kendi dizin adını kayıt anahtarı olarak kullanır.
Log Dosyası Şişerse Ne Olur?#
debug.log kendi kendine dönmez, kırpılmaz, sınırlanmaz. Sitede saniyede birkaç kez tetiklenen bir Notice varsa dosya bir gecede yüzlerce megabayta çıkabilir. Sonuç, çözmeye çalıştığınızdan daha büyük bir problem olur: disk kotası dolar, siteye yeni dosya yüklenemez, veritabanı yazamaz hâle gelir.
Bu yüzden log açıkken boyutu takip edin:
ls -lh ~/logs/wp-debug.log
du -sh ~/logs/
# Dosyayı silmeden sıfırla (PHP açık tutuyorsa silmek yerine bu tercih edilir)
: > ~/logs/wp-debug.log
# ya da
truncate -s 0 ~/logs/wp-debug.log
Dosyayı rm ile silmek çoğu durumda çalışır ama PHP-FPM süreci dosya tanıtıcısını açık tutuyorsa yazmaya silinen dosyaya devam eder ve disk alanı süreç yeniden başlayana kadar geri gelmez. truncate -s 0 bu sorunu yaşatmaz.
Aynı log satırı binlerce kez tekrar ediyorsa çözüm logu büyütmek değil, o uyarıyı üreten kodu düzeltmek ya da eklentiyi değiştirmektir. Hangi mesajın kaç kez tekrarlandığını hızlıca çıkarmak için:
grep -oP 'PHP \w+ error:.*?(?= in /)' ~/logs/wp-debug.log | sort | uniq -c | sort -rn | head
debug.log ile Sunucunun error_log'u Aynı Şey Değil#
Karışan iki farklı kayıt var:
debug.log— WordPress'in yönlendirdiği PHP hata çıktısıdır. Sadece PHP seviyesinde olan biteni içerir ve yalnız siz açtığınızda dolar.- Sunucu hata kaydı — Apache/Nginx ya da PHP-FPM'in kendi tuttuğu kayıttır. cPanel'de "Hata Kayıtları" bölümünde, veya
~/logs/altındaerror_logadıyla durur. WordPress hiç açılamadığında (.htaccessbozuk, PHP sürümü uyumsuz, bellek limiti aşıldı) hata buraya düşer,debug.log'a düşmez.
Site tamamen açılmıyorsa ve debug.log boşsa ya da hiç oluşmuyorsa, bakılacak yer ikincisidir. cPanel kullanıyorsanız cPanel hata kayıtları yazısı bu ekranı anlatıyor. PHP'nin hata raporlama davranışını WordPress'ten bağımsız olarak nasıl yapılandırdığınızı görmek için de PHP hata raporlama rehberine bakabilirsiniz.
İşe Yarayan Diğer Hata Ayıklama Sabitleri#
WP_DEBUG ailesinin yanında, doğru anda açıldığında zaman kazandıran birkaç sabit daha var:
// Çekirdeğin küçültülmemiş (.min olmayan) JS/CSS dosyalarını yükler.
// Tarayıcı konsolundaki bir hatanın hangi satırdan geldiğini görmek için.
define( 'SCRIPT_DEBUG', true );
// Sayfa yüklenirken çalışan tüm SQL sorgularını $wpdb->queries içinde tutar.
// Yavaşlık teşhisinde işe yarar, bellek tüketir; canlıda uzun süre açık kalmamalı.
define( 'SAVEQUERIES', true );
// Eklentileri kendi dosya değişiklikleriyle test ederken tarayıcı önbelleğini kırar.
define( 'CONCATENATE_SCRIPTS', false );
SAVEQUERIES tek başına bir çıktı üretmez; verdiği diziyi okuyan bir araca ihtiyaç duyar. Pratikte çoğu kişi bu iş için Query Monitor benzeri bir geliştirici eklentisi kurar; hangi sorgunun ne kadar sürdüğünü, hangi hook'un hangi callback'i çağırdığını yönetici çubuğunda gösterir. Bu tür bir eklenti canlı sitede kalıcı olarak açık bırakılmamalıdır.
İş Bitince Kapatmayı Unutmayın#
Hata ayıklamayı açık unutmak, çözdüğünüz sorundan daha uzun ömürlü bir sorun yaratır. Kapatma listesi:
wp-config.phpiçindeWP_DEBUGdeğerinifalseyapın.WP_DEBUG_DISPLAYveWP_DEBUG_LOGsatırlarını silebilir ya da bırakabilirsiniz;WP_DEBUGkapalıyken ikisi de etkisizdir.WP_DISABLE_FATAL_ERROR_HANDLEReklediyseniz mutlaka kaldırın.SCRIPT_DEBUGveSAVEQUERIESsatırlarını temizleyin — ikisi de her sayfa yüklemesine ölçülebilir bir maliyet ekler.- Log dosyasını silin ya da sıfırlayın. Log web kökünde kaldıysa artık gereksiz bir bilgi sızıntısı kaynağıdır.
- Kurduysanız hata ayıklama eklentisini pasife alın veya kaldırın.
Kalıcı bir çözüm isterseniz sabitleri sabit değer yerine bir ortam koşuluna bağlayabilirsiniz; böylece test kopyanızda açık, canlıda kapalı kalır:
$cloutr_hata_ayikla = ( 'test.siteniz.com' === ( $_SERVER['HTTP_HOST'] ?? '' ) );
define( 'WP_DEBUG', $cloutr_hata_ayikla );
define( 'WP_DEBUG_DISPLAY', false );
define( 'WP_DEBUG_LOG', $cloutr_hata_ayikla );
Bu yaklaşım, wp-config.php dosyasını iki ortam arasında kopyalarken hata ayıklamanın yanlışlıkla canlıya taşınmasını da engeller. wp-config.php içindeki diğer güvenlik ayarları için wp-config güvenlik yazısına göz atın.
Sıkça Sorulan Sorular#
debug.log dosyası oluşmuyor, ne yapmalıyım?#
Üç olası sebep var. Birincisi, WP_DEBUG sabiti false kalmış ya da dosyada iki kez tanımlanmış olabilir — ilk tanım geçerli olduğu için ikincisi hiç işlemez. İkincisi, sabitler /* That's all, stop editing! */ satırından sonraya yazılmıştır ve WordPress çoktan başlamıştır. Üçüncüsü, hedef dizinde yazma izni yoktur; wp-content için 755, dosya oluşturulduktan sonra debug.log için 644 uygundur. Ayrıca henüz hiç hata oluşmadıysa dosya da oluşmaz.
WP_DEBUG'ı canlı sitede açmak güvenli mi?#
WP_DEBUG_DISPLAY sabiti açıkça false yapıldığı ve log dosyası web'den erişilemeyecek bir yerde durduğu sürece güvenlidir; ziyaretçiler hiçbir fark görmez. Bu iki koşuldan biri eksikse güvenli değildir: hata mesajları sunucu yollarınızı ve kurulum detaylarınızı açığa çıkarır. Yine de gerekenden uzun süre açık bırakmayın, çünkü log dosyası büyüyerek disk kotanızı doldurabilir.
Logda yüzlerce "Deprecated" satırı var, sitem tehlikede mi?#
Hayır. Deprecated uyarıları, bir eklentinin PHP'nin ileride kaldıracağı bir yapıyı kullandığını söyler; site şu an sorunsuz çalışır. PHP sürümünüzü yükselttiğinizde bu satırlar toplu hâlde ortaya çıkar. Yapılacak şey ilgili eklenti ve temaların güncel sürümde olduğundan emin olmak, uzun süredir güncellenmeyen eklentiler için alternatif aramaktır. Acil bir müdahale gerektirmez.
debug.log içindeki saatler neden geri?#
WordPress, PHP'nin varsayılan saat dilimini UTC olarak sabitler ve PHP hata kayıtlarına damgayı bu dilime göre atar. Türkiye saati UTC+3 olduğu için log satırları sizin saatinizden üç saat geride görünür. Bir olayı zamana göre ararken saatinizden 3 çıkarın. Yönetici panelindeki tarihler bundan etkilenmez; onlar sitenin ayarlarındaki saat dilimine göre gösterilir.
Panele hiç giremiyorum, wp-config.php'yi nasıl düzenlerim?#
Hosting kontrol panelinizin dosya yöneticisi ya da bir FTP/SFTP istemcisi yeterlidir; wp-config.php sitenin kök dizininde, wp-admin ve wp-content klasörleriyle aynı seviyededir. SSH erişiminiz varsa nano ya da vi ile doğrudan düzenleyebilirsiniz. Düzenlemeden önce mutlaka bir kopyasını alın: bu dosyadaki bir yazım hatası, örneğin kapatılmamış bir tırnak, siteyi tamamen erişilemez hâle getirir.
Query Monitor gibi bir eklenti kurmak yerine neden log kullanayım?#
Geliştirici eklentileri panele girebiliyorsanız çok daha okunaklıdır, ancak site tamamen çökmüşse yönetici paneli de açılmaz — eklenti size hiçbir şey gösteremez. debug.log ise WordPress'in yarım kaldığı anda bile yazılır, çünkü kaydı yapan PHP'nin kendisidir. Pratik yaklaşım ikisini birlikte kullanmaktır: ölümcül hatalar için log, performans ve sorgu incelemesi için eklenti.