PHP'de "Headers Already Sent" Hatası Neden Olur?

Headers Already Sent (Türkçe: "Başlıklar Zaten Gönderildi") hatası, PHP uygulamalarında sık karşılaşılan ve genellikle yönlendirme, session yönetimi veya çerez ayarlamaları sırasında uygulamanın beklenmedik şekilde başarısız olmasına neden olan bir hatadır. Bu rehberde hatanın teknik kökenlerini, hızlı teşhis adımlarını ve kalıcı çözümleri bulacaksınız.

Giriş — Hata ne anlama gelir?

HTTP başlıkları (headers), tarayıcıya içerik türü, yönlendirme (Location), çerezler ve oturum bilgileri gibi meta bilgilerdir. PHP, bu başlıkları göndermeden önce herhangi bir çıktı (HTML, boş satır, boşluk, echo/print vb.) gönderildiğini tespit ederse "Cannot modify header information - headers already sent" uyarısını verir. Bu durumda header(), setcookie() veya session_start() gibi fonksiyonlar beklenen şekilde çalışmaz.

Gelişme — En yaygın nedenler ve arkasındaki mantık

1. Dosyaların başında/sonunda istemeden gönderilen çıktı

  • PHP etiketleri dışındaki boşluklar veya yeni satırlar. Özellikle include/require yapılan dosyalarda başlık öncesi istem dışı boşluk olması sık rastlanan bir sebeptir.
  • echo/print veya HTML ile doğrudan çıktı gönderilmesi. header() çağrısından önce herhangi bir çıktı varsa hatayla karşılaşılır.

2. UTF-8 BOM (Byte Order Mark)

Dosya UTF-8 BOM ile kaydedildiyse BOM, dosyanın başında görünmez bir çıktı oluşturur. Bu küçük bayt dizisi bile başlıkların gönderilmesini engeller. PHP dosyalarını "UTF-8 without BOM" olarak kaydetmek çözüm sağlar.

3. Kapanış PHP etiketi (?>) ve sonrası

Bir PHP dosyasının sonunda gereksiz kapatma etiketi varsa ve sonrasında boşluk veya yeni satır varsa bu çıktı olarak değerlendirilir. Modern PHP uygulamalarında son kapanış etiketi çoğunlukla kaldırılır.

4. Oturum (session) ve çerez (cookie) çağrılarının yanlış yerde olması

session_start() veya setcookie() gibi fonksiyonlar header katmanında işlem yaptıkları için, bunlar her zaman herhangi bir çıktan önce çağrılmalıdır. İşlem içine dahil edilen dosyalarda istemeden çıktı varsa session başlatma başarısız olur.

5. Dahil edilen (include/require) dosyalardaki beklenmedik çıktı

Projenizde kullandığınız kütüphaneler, konfigürasyon dosyaları veya pluggable dosyalar (ör. bazı CMS çekirdek dosyaları) istemeden çıktı üretiyor olabilir. Hata mesajları genellikle "output started at /path/to/file.php:line" şeklinde ilgili dosya ve satırı gösterir; burası ilk bakılması gereken yerdir.

Hızlı teşhis adımları (checklist)

  • Hata mesajını okuyun: Mesajda genellikle hangi dosyada ve hangi satırda çıktının başladığı yazar. Oradan başlayın.
  • Dosya başlarını kontrol edin:
  • Dosya sonlarını kontrol edin: Kapanış PHP etiketi (?>) varsa silmeyi deneyin veya sonrasında boşluk olmadığından emin olun.
  • Encoding kontrolü: Dosyaları UTF-8 without BOM ile kaydedin.
  • Include edilen dosyaları inceleyin: echo/print, var_dump veya debug çıktıları var mı?
  • Output buffering testi: Geçici olarak ob_start() ekleyip hatanın kaybolup kaybolmadığını kontrol edin (ancak bu sadece semptomu gizleyebilir, kök neden çözümü tercihtir).

Pratik çözümler ve örnekler

Örnek 1 — Yönlendirme (redirect) hatasını düzeltme

<?php
// DOĞRU: header() çağrısı çıktıdan önce
header('Location: /yeni-sayfa.php');
exit;
?>

Örnek 2 — Oturumu doğru başlatma

<?php
// DOĞRU: session_start() HTML çıktıdan önce çağrılmalı
session_start();
// ... uygulama mantığı
?>

Geçici çözüm: Output buffering

Hatanın kök nedenini hemen bulamıyorsanız, giriş betiğinin en başına ob_start() eklemek işe yarayabilir. Ancak uzun vadede dosyalardaki istem dışı çıktıları temizlemek daha doğrudur.

<?php
ob_start();
// Uygulama kodu
// Eğer gerekiyorsa ob_end_flush(); ile tamponu boşaltın
?>

Önleyici uygulama ve en iyi pratikler

  • Dosya encoding standardı: Tüm proje dosyalarını UTF-8 (BOM yok) olarak saklayın.
  • Kapanış etiketi kullanmayın: PHP dosyalarının sonundaki ?> etiketi çoğu zaman gereksizdir; kaldırmak güvenlidir ve çıktıyı engeller.
  • Kontrol edilmiş giriş/çıktı akışı: Tüm header/redirect/session işlemlerini uygulama akışının üst katmanlarında yapın.
  • Geliştirme ortamı kontrolleri: CI süreçlerinde veya kod incelemelerinde dosya encoding ve fazladan whitespace için otomatik kontroller ekleyin.
  • Debugleme: Hata mesajındaki dosya/satır bilgilerini referans alarak, include zincirini izleyin.

Sonuç — Hatanın kökünü temizlemek sürdürülebilir

"Headers Already Sent" hatası genelde küçük ve görünmez nedenlerden (BOM, boşluk, gereksiz kapanış etiketi) kaynaklanır; ancak sonuçları yönlendirmeler, oturum yönetimi ve çerez işlemlerinde ciddi problemlere neden olabilir. Hızlı çözümler (ob_start gibi) pratik olsa da, en sağlam yaklaşım dosya encoding'ini düzeltmek, çıktıyı kontrol etmek ve header işlemlerini doğru yerde gerçekleştirmektir. Bu adımlar uygulandığında hem hatalar azalır hem de uygulamanın güvenilirliği artar.

Kısa Özet (Checklist):

  • Hata mesajındaki file:line'ı kontrol et.
  • Dosyaları "UTF-8 without BOM" ile kaydet.
  • PHP kapanış etiketlerini son dosyalardan kaldır.
  • header()/session_start()/setcookie() çağrılarını çıktıdan önce yap.
  • Gerekirse ob_start() ile geçici tamponlama kullan, ama kök nedeni düzelt.

Uygulama bakımında sistematik kontrol ve kod standardizasyonu, bu tip hataları üretim ortamında en aza indirmek için en etkili yaklaşımdır.