Sitemizi ziyaret eden kullanıcıların tarayıcıları ile php sunucumuz http protokolü kullanarak iletişim kurarlar. Örneğin echo veya print_r gibi çıktı oluşturduğumuz fonksiyonlar kullanarak tarayıcıya veri gönderirken, http protokolü kullanıldığından dolayı http header ile gönderilir. Header gönderildikten sonra veri gönderilmeye devam edebilir.
Php’de http cevapları script sonlanınca veya buffer dolunca gönderilir. Şimdi local ortamımızdaki output_buffering değerini kontrol edelim. Index.php dosyamıza phpinfo(); yazıp tarayıcıda çalıştıralım. Resimde görüldü gibi değeri 4096 yani 4 kb.
Output buffer değeri 4 kb ayarlı iken ilk örnek kodumuzu yazıp çalıştıralım.
Tarayıcımızda localhost:8000 yazıp enter’e basınca 3 sn. bekledi ve ekrana resimdeki gibi bir çıktı verdi. Önce 3.satırdaki echo komutu ile bir çıktı oluşturdu ancak göndermek yerine buffer’da tuttu, sonra 3 sn. bekledi ve 7.satırdaki echo ile bir çıktı daha oluşturdu ve buffer dolmadığı için gene göndermedi fakat script burada bittiği için http cevabımız artık gönderildi. Bu durumda 7.satıra kadar yani script sonlana kadar http cevabımız gönderilmediği için, örneğin http header’da değişiklik yapabiliriz. Örneğin http status code’unu 206 olarak ayarlayalım.
Gördüğünüz gibi, tarayıcının geliştirici aracını açıp ağ sekmesine baktığımız zaman durum kodunun 200 değil 206 olarak görüyoruz.
Şimdi output_buffering değerini 0 yapıp tekrar deneyelim. Bunun için php.ini dosyasına gidip output_buffering = 0 olarak güncelliyoruz. Sonrasında control + c ile development server’imizi durdurup php -S localhost:8000 ile tekrar çalıştırıyoruz. Tekrar phpinfo(); fonskiyonu ile kontrol edebilirsiniz.
Aynı kodumuzu bu sefer output_buffering değeri 0 iken çalıştırıp sonuçlarını görelim.
Script çalışırken 3.satıra gelince buffer değerimiz 0 olduğu için ilk çıktı işleminde http cevabını gönderdi. Haliyle header gönderilmiş oldu. Tarayıcıda ekrana “ilk çıktı” değerini bastı ve 3 sn bekledi. Sonrasında “ikinci çıktı” değerini bastı ve yükleme tamamlandı. Ancak resimde de görüldüğü gibi durum kodu 206 değil 200 olarak geldi. Çünkü ilk çıktı işlemi ile birlikte http başlığı zaten gönderildiği için 9.satırdaki kod ile durum kodunu değiştiremedik.
Örneğin cookie bilgileri de header ile gönderilir. 9. satırı durum kodu değilde cookie göndermek için şu şekilde değiştirelim ve sonucu görelim:
setcookie(“cookie”, “value”);
İlk çıktı basıldı 3.sn bekledi ve ikinci çıktıyı bastıktan sonra hata verdi. Hata mesajında, header bilgilerini değiştiremezsin çünkü zaten header gönderildi. Çünkü 3.satırda çıktı işlemi başladı.
Output buffering kapalı iken de output buffering işlemi yapabiliriz. Bunun için ob_start() fonksiyonu kullanıyoruz.
Bu kodda çıktılar buffer’da bekletilip 13. satırdaki ob_end_flush() ile gönderilecek.
Burada dikkat etmemiz gereken nokta ob_start() fonksiyonunu kullanmadan önce herhangi bir çıktı işlemi yapılmamış olmalı. Ayrıca ob_end_flush 'dan sonra da çıktı verebiliriz tabii ki setcookie gibi header bilgilerini değiştirme girişiminde bulunmamak kaydıyla.
Resimde görüldüğü gibi kodumu 206 oldu ve ekrana 3 çıktıyı da bastı.
Nasıl çalıştığını inceleyelim. 6.satıra kadar bazı değişkenler tanımladık. Çıktı işlemi olmadığı için sorun olmadı. 6.satırda ob_start() ile tamponlama (buffering) işlemine başladık. 17.satıra kadar işlemler gerçekleşti ama ekrana bir şey basmadı. 17. satırda ise ekrana “ilk çıktı” ve “ikinci çıktı” değelerini bastı. Bu aşamada header gönderilmiş oldu. 17.satırdan sonra header bilgilerini değiştiren bir işlem yapmadık. 3 sn daha beklettikten sonra “üçüncü çıktı” metinini gönderdik ve o da sorunsuz bir şekilde görüntülendi ve herhangi bir hata almadık.
İnternette “header already sent hatası” şeklinde arattığınızda sayfanın en başına hiçbir şey yazmadan ob_start() yazın gibi hazır cevaplar bulabilirsiniz. Evet bu sorununuzu belki çözecektir ama aslında ne olduğunu bilmeden ezbere ve şansa bir çözüm olacaktır.