Saat menjalankan skrip saya, saya mendapatkan beberapa kesalahan seperti ini:
Peringatan: Tidak dapat mengubah informasi header - header sudah dikirim oleh ( output dimulai pada /some/file.php:12 ) di /some/file.php on line 23
Baris yang disebutkan dalam pesan kesalahan berisi header()
dan setcookie()
panggilan.
Apa yang bisa menjadi alasan untuk ini? Dan bagaimana cara memperbaikinya?
ob_start
danob_end_clean()
mungkin terbukti bermanfaat di sini). Anda kemudian dapat mengatur cookie atau sesi sama denganob_get_contents()
dan kemudian gunakanob_end_clean()
untuk menghapus buffer.safeRedirect
fungsi di Perpustakaan PHP saya: github.com/heinkasner/PHP-Library/blob/master/extra.phpUTF-8
, tetapiUTF-8 (Without BOM)
~~~~~~~~~~~Jawaban:
Tidak ada output sebelum mengirim header!
Fungsi yang mengirim / memodifikasi header HTTP harus dipanggil sebelum output apa pun dibuat . summary ⇊ Kalau tidak, panggilan gagal:
Beberapa fungsi yang memodifikasi tajuk HTTP adalah:
header
/header_remove
session_start
/session_regenerate_id
setcookie
/setrawcookie
Output dapat:
Tak disengaja:
<?php
atau sesudah?>
Disengaja:
print
,echo
dan fungsi lainnya yang menghasilkan keluaran<html>
Bagian mentah<?php
kode sebelumnya .Mengapa itu terjadi?
Untuk memahami mengapa header harus dikirim sebelum output, perlu melihat respons HTTP khas . Script PHP terutama menghasilkan konten HTML, tetapi juga meneruskan satu set header HTTP / CGI ke server web:
Halaman / output selalu mengikuti header. PHP harus meneruskan header ke server web terlebih dahulu. Itu hanya bisa dilakukan sekali. Setelah double linebreak, mereka tidak akan pernah bisa mengubahnya lagi.
Ketika PHP menerima output pertama (
print
,echo
,<html>
) itu akan menyiram semua header dikumpulkan. Setelah itu dapat mengirim semua output yang diinginkan. Tetapi mengirimkan tajuk HTTP lebih lanjut tidak mungkin dilakukan.Bagaimana Anda bisa mengetahui di mana output prematur terjadi?
The
header()
peringatan berisi semua informasi yang relevan untuk menemukan masalah penyebab:Di sini "baris 100" merujuk ke skrip tempat
header()
doa gagal.Catatan " output dimulai pada " dalam kurung lebih signifikan. Ini menunjukkan sumber output sebelumnya. Dalam contoh ini itu
auth.php
dan garis52
. Di situlah Anda harus mencari hasil prematur.Penyebab khas:
Cetak, gema
Output
print
danecho
pernyataan yang disengaja akan menghentikan kesempatan untuk mengirim header HTTP. Alur aplikasi harus disusun ulang untuk menghindari itu. Gunakan fungsi dan skema templating. Pastikanheader()
panggilan terjadi sebelum pesan ditulis.Fungsi yang menghasilkan keluaran termasuk
print
,echo
,printf
,vprintf
trigger_error
,ob_flush
,ob_end_flush
,var_dump
,print_r
readfile
,passthru
,flush
,imagepng
,imagejpeg
antara lain dan fungsi yang ditentukan pengguna.
Area HTML mentah
Bagian HTML yang tidak diurai dalam
.php
file juga merupakan output langsung. Kondisi skrip yang akan memicuheader()
panggilan harus dicatat sebelum ada<html>
blok mentah .Gunakan skema templating untuk memisahkan pemrosesan dari logika output.
Spasi sebelumnya
<?php
untuk peringatan "script.php line 1 "Jika peringatan mengacu pada keluaran sejalan
1
, maka sebagian besar mengarah spasi putih , teks atau HTML sebelum<?php
token pembuka .Demikian pula dapat terjadi untuk skrip yang ditambahkan atau bagian skrip:
PHP sebenarnya memakan satu linebreak setelah tag penutup. Tapi itu tidak akan mengkompensasi beberapa baris baru atau tab atau spasi bergeser ke celah seperti itu.
UTF-8 BOM
Linebreak dan spasi saja bisa menjadi masalah. Tetapi ada juga urutan karakter "tidak terlihat" yang dapat menyebabkan ini. Paling terkenal adalah UTF-8 BOM (Byte-Order-Mark) yang tidak ditampilkan oleh kebanyakan editor teks. Ini urutan byte
EF BB BF
, yang merupakan opsional dan berlebihan untuk dokumen yang disandikan UTF-8. Namun PHP harus memperlakukannya sebagai output mentah. Ini mungkin muncul sebagai karakter
dalam output (jika klien menafsirkan dokumen sebagai Latin-1) atau "sampah" serupa.Secara khusus editor grafis dan IDE berbasis Java tidak menyadari keberadaannya. Mereka tidak memvisualisasikannya (diwajibkan oleh standar Unicode). Namun sebagian besar programmer dan editor konsol melakukan:
Di sana mudah untuk mengenali masalah sejak dini. Editor lain dapat mengidentifikasi keberadaannya dalam menu file / pengaturan (Notepad ++ pada Windows dapat mengidentifikasi dan memperbaiki masalah ), Pilihan lain untuk memeriksa keberadaan BOM adalah beralih ke hexeditor . Sistem On * nix
hexdump
biasanya tersedia, jika bukan varian grafis yang menyederhanakan audit ini dan masalah lain:Perbaikan yang mudah adalah dengan mengatur editor teks untuk menyimpan file sebagai "UTF-8 (tanpa BOM)" atau nomenklatur semacam itu. Seringkali pendatang baru sebaliknya membuat file baru dan hanya menyalin & menempel kembali kode sebelumnya.
Utilitas koreksi
Ada juga alat otomatis untuk memeriksa dan menulis ulang file teks (
sed
/awk
ataurecode
). Khusus untuk PHP adaphptags
tag yang lebih rapi . Ini menulis ulang tag dekat dan terbuka ke dalam bentuk panjang dan pendek, tetapi juga dengan mudah memperbaiki spasi putih terkemuka, Unicode dan UTF-x BOM:Itu wajar untuk digunakan pada keseluruhan termasuk atau direktori proyek.
Spasi setelah
?>
Jika sumber kesalahan disebutkan sebagai di balik penutupan
?>
maka ini adalah tempat spasi putih atau teks mentah ditulis. Penanda akhir PHP tidak menghentikan eksekusi skrip pada saat ini. Setiap karakter teks / spasi setelah itu akan ditulis sebagai konten halaman.Biasanya disarankan, khususnya bagi para pendatang baru, agar
?>
tag dekat PHP harus dihilangkan. Ini menghindari sebagian kecil dari kasus-kasus ini. (Cukup umuminclude()d
skrip adalah pelakunya.)Sumber kesalahan disebutkan sebagai "Tidak dikenal pada baris 0"
Ini biasanya merupakan ekstensi PHP atau pengaturan php.ini jika tidak ada sumber kesalahan yang dikonkretkan.
gzip
pengaturan penyandian aliran atauob_gzhandler
.extension=
modul berlipat ganda yang menghasilkan startup PHP / pesan peringatan implisit.Pesan kesalahan sebelumnya
Jika pernyataan atau ekspresi PHP lain menyebabkan pesan peringatan atau pemberitahuan dicetak, itu juga dianggap sebagai hasil prematur.
Dalam hal ini Anda perlu menghindari kesalahan, menunda eksekusi pernyataan, atau menekan pesan dengan misalnya
isset()
atau@()
- ketika salah satu tidak menghalangi proses debug nanti.Tidak ada pesan kesalahan
Jika Anda memiliki
error_reporting
ataudisplay_errors
menonaktifkan perphp.ini
, maka tidak ada peringatan akan muncul. Tetapi mengabaikan kesalahan tidak akan membuat masalah hilang. Header masih tidak dapat dikirim setelah output prematur.Jadi, ketika
header("Location: ...")
pengalihan gagal secara diam-diam, sangat disarankan untuk memeriksa peringatan. Aktifkan kembali dengan dua perintah sederhana di atas skrip doa:Atau
set_error_handler("var_dump");
jika semuanya gagal.Berbicara tentang redirect header, Anda harus sering menggunakan idiom seperti ini untuk jalur kode akhir:
Lebih disukai bahkan fungsi utilitas, yang mencetak pesan pengguna dalam kasus
header()
kegagalan.Output buffering sebagai solusi
Output buffering PHPs adalah solusi untuk mengatasi masalah ini. Ini sering bekerja dengan andal, tetapi seharusnya tidak menggantikan struktur aplikasi yang tepat dan memisahkan output dari logika kontrol. Tujuan sebenarnya adalah meminimalkan transfer chunked ke server web.
The
output_buffering=
Pengaturan demikian dapat membantu. Konfigurasikan di php.ini atau via .htaccess atau bahkan .user.ini pada pengaturan FPM / FastCGI modern.Mengaktifkannya akan memungkinkan PHP melakukan buffer output alih-alih meneruskannya ke server web secara instan. PHP dengan demikian dapat mengagregasi header HTTP.
Itu juga dapat digunakan dengan panggilan untuk
ob_start();
di atas skrip doa. Namun yang kurang dapat diandalkan karena berbagai alasan:Bahkan jika
<?php ob_start(); ?>
memulai skrip pertama, spasi putih atau BOM mungkin akan dikocok sebelumnya, menjadikannya tidak efektif .Itu dapat menyembunyikan spasi untuk output HTML. Tetapi begitu logika aplikasi mencoba untuk mengirim konten biner (gambar yang dihasilkan misalnya), output asing buffered menjadi masalah. (Diperlukan
ob_clean()
sebagai solusi lebih jauh.)Ukuran buffer terbatas, dan dapat dengan mudah dibanjiri ketika dibiarkan default. Dan itu juga bukan kejadian langka, sulit dilacak ketika itu terjadi.
Kedua pendekatan karena itu dapat menjadi tidak dapat diandalkan - khususnya ketika beralih antara pengaturan pengembangan dan / atau server produksi. Itulah sebabnya output buffering secara luas dianggap hanya sebagai penopang / hanya solusi.
Lihat juga contoh penggunaan dasar dalam manual, dan untuk lebih banyak pro dan kontra:
Tapi itu berhasil di server lain !?
Jika Anda tidak mendapatkan peringatan header sebelumnya, maka pengaturan buffer php.ini output telah berubah. Kemungkinan tidak terkonfigurasi pada server saat ini / baru.
Memeriksa dengan
headers_sent()
Anda selalu dapat menggunakan
headers_sent()
untuk menyelidiki jika masih memungkinkan untuk ... mengirim header. Yang berguna untuk mencetak informasi secara kondisional atau menerapkan logika fallback lainnya.Solusi fallback yang berguna adalah:
<meta>
Tag HTMLJika aplikasi Anda secara struktural sulit untuk diperbaiki, maka cara mudah (tapi agak tidak profesional) untuk memungkinkan pengalihan adalah menyuntikkan
<meta>
tag HTML . Pengalihan dapat dicapai dengan:Atau dengan penundaan singkat:
Ini mengarah ke HTML yang tidak valid ketika digunakan melewati
<head>
bagian. Sebagian besar browser masih menerimanya.Pengalihan JavaScript
Sebagai alternatif, pengalihan JavaScript dapat digunakan untuk pengalihan halaman:
Meskipun ini sering lebih sesuai dengan HTML daripada
<meta>
solusinya, ini menimbulkan ketergantungan pada klien yang berkemampuan JavaScript.Namun kedua pendekatan membuat fallback yang dapat diterima ketika panggilan HTTP asli () gagal. Idealnya Anda akan selalu menggabungkan ini dengan pesan yang ramah pengguna dan tautan yang dapat diklik sebagai pilihan terakhir. (Yang misalnya adalah apa yang http_redirect () ekstensi PECL .)
Mengapa
setcookie()
dansession_start()
juga terpengaruhKeduanya
setcookie()
dansession_start()
perlu mengirimSet-Cookie:
header HTTP. Karena itu, kondisi yang sama berlaku, dan pesan kesalahan serupa akan dihasilkan untuk situasi keluaran prematur.(Tentu saja mereka lebih jauh dipengaruhi oleh cookie yang dinonaktifkan di browser, atau bahkan masalah proxy. Fungsi sesi jelas juga tergantung pada ruang disk kosong dan pengaturan php.ini lainnya, dll.)
Tautan selanjutnya
sumber
?>
dari akhir file php biasanya merupakan praktik yang baik yang membantu meminimalkan kesalahan ini juga. Ruang kosong yang tidak diinginkan tidak akan muncul di akhir file, dan Anda masih dapat menambahkan header ke respons nanti. Ini juga berguna jika Anda menggunakan buffering output, dan tidak ingin melihat spasi kosong yang tidak diinginkan di akhir bagian yang dihasilkan oleh file yang disertakan.Pesan kesalahan ini terpicu ketika ada sesuatu yang dikirim sebelum Anda mengirim header HTTP (dengan
setcookie
atauheader
). Alasan umum untuk menghasilkan sesuatu sebelum header HTTP adalah:Ruang kosong yang tidak disengaja, sering di awal atau di akhir file, seperti ini:
Untuk menghindarinya, cukup tutup saja
?>
- itu tidak wajib.3F 3C
. Anda dapat dengan aman menghapus BOMEF BB BF
dari awal file.echo
,printf
,readfile
,passthru
, kode sebelum<?
dlldisplay_errors
properti php.ini diatur. Alih-alih menabrak kesalahan programmer, php diam-diam memperbaiki kesalahan dan memancarkan peringatan. Meskipun Anda dapat mengubah konfigurasidisplay_errors
atau error_reporting , Anda sebaiknya memperbaiki masalahnya.Alasan umum adalah akses ke elemen array yang tidak terdefinisi (seperti
$_POST['input']
tanpa menggunakanempty
atauisset
untuk menguji apakah input diatur), atau menggunakan konstanta yang tidak terdefinisi alih-alih string literal (seperti dalam$_POST[input]
, perhatikan tanda kutip yang hilang).Mengaktifkan buffering output harus membuat masalah hilang; semua output setelah panggilan ke
ob_start
buffer dalam memori sampai Anda melepaskan buffer, misalnya denganob_end_flush
.Namun, sementara buffering output menghindari masalah, Anda harus benar-benar menentukan mengapa aplikasi Anda mengeluarkan badan HTTP sebelum header HTTP. Itu seperti menerima panggilan telepon dan mendiskusikan hari Anda dan cuaca sebelum memberi tahu penelepon bahwa ia mendapat nomor yang salah.
sumber
Saya mendapatkan kesalahan ini beberapa kali sebelumnya, dan saya yakin semua programmer PHP mendapat kesalahan ini setidaknya sekali sebelumnya.
Kemungkinan Solusi 1
Kesalahan ini mungkin disebabkan oleh ruang kosong sebelum awal file atau setelah akhir file. Ruang kosong ini seharusnya tidak ada di sini.
ex) TIDAK HARUS MENJADI RUANG KOSONG DI SINI
Periksa semua file yang terkait dengan file yang menyebabkan kesalahan ini.
Catatan: Terkadang EDITOR (IDE) seperti gedit (editor linux default) menambahkan satu baris kosong pada file save. Ini seharusnya tidak terjadi. Jika Anda menggunakan Linux. Anda dapat menggunakan editor VI untuk menghapus spasi / baris setelah?> di akhir halaman.
Kemungkinan Solusi 2: Jika ini bukan kasus Anda, gunakan ob_start untuk menghasilkan buffering:
Ini akan mengaktifkan buffering output dan header Anda akan dibuat setelah halaman buffer.
sumber
ob_start()
hanya menyembunyikan masalahnya; jangan menggunakannya untuk menyelesaikan masalah khusus ini.ob_start()
, maka apa yang harus saya lakukan untuk menyelesaikan masalah ini:Headers already sent
ob_start()
tidak "menyembunyikan" masalahnya, itu memecahkan masalah.Alih-alih baris di bawah ini
menulis
atau
Ini pasti akan menyelesaikan masalah Anda. Saya menghadapi masalah yang sama tetapi saya menyelesaikan dengan menulis lokasi header dengan cara di atas.
sumber
Kamu lakukan
sebelum mengatur cookie, yang tidak diizinkan. Anda tidak dapat mengirim output apa pun sebelum header, bahkan garis kosong.
sumber
Itu karena baris ini:
Anda tidak boleh mencetak / menggemakan apa pun sebelum mengirim header.
sumber
MASALAH UMUM:
(disalin dari: sumber )
====================
1) seharusnya tidak ada output (yaitu
echo..
kode HTML atau) sebelumheader(.......);
perintah.2) hapus spasi putih (atau baris baru ) sebelum
<?php
dan sesudah?>
tag.3) ATURAN EMAS! - periksa apakah file php (dan juga, jika Anda
include
file lain) memiliki UTF8 tanpa pengkodean BOM (dan bukan hanya UTF-8 ). Itu masalah dalam banyak kasus (karena file yang disandikan UTF8 memiliki sesuatu karakter khusus di awal file php, yang tidak ditampilkan oleh editor teks Anda) !!!!!!!!!!!4) Setelah
header(...);
Anda harus menggunakanexit;
5) selalu menggunakan referensi 301 atau 302:
6) Aktifkan pelaporan kesalahan, dan temukan kesalahan tersebut. Kesalahan Anda mungkin disebabkan oleh fungsi yang tidak berfungsi. Saat Anda mengaktifkan pelaporan kesalahan, Anda harus selalu memperbaiki kesalahan paling atas terlebih dahulu. Misalnya, mungkin "Peringatan: date_default_timezone_get (): Tidak aman untuk bergantung pada pengaturan zona waktu sistem." - lalu lebih jauh ke bawah Anda mungkin melihat kesalahan "header tidak terkirim". Setelah memperbaiki kesalahan paling atas (ke-1), muat ulang halaman Anda. Jika Anda masih memiliki kesalahan, maka perbaiki kesalahan paling atas.
7) Jika tidak ada di atas yang membantu, gunakan pengalihan JAVSCRIPT (namun, metode yang sangat tidak disarankan), mungkin merupakan kesempatan terakhir dalam kasus khusus ...:
sumber
301
atau302
penting?Kiat sederhana: Ruang sederhana (atau karakter khusus yang tidak terlihat) di skrip Anda, tepat sebelum
<?php
tag pertama , dapat menyebabkan ini! Terutama ketika Anda bekerja dalam tim dan seseorang menggunakan IDE "lemah" atau telah mengacaukan file dengan editor teks aneh.Saya telah melihat hal-hal ini;)
sumber
Praktik buruk lainnya dapat memicu masalah ini yang belum dinyatakan.
Lihat cuplikan kode ini:
Semuanya baik-baik saja, bukan?
Bagaimana jika "a_important_file.php" adalah ini:
Ini tidak akan bekerja Kenapa? Karena sudah dihasilkan baris baru.
Sekarang, meskipun ini bukan skenario umum bagaimana jika Anda menggunakan kerangka kerja MVC yang memuat banyak file sebelum menyerahkan sesuatu ke controller Anda? Ini bukan skenario yang tidak biasa. Bersiaplah untuk ini.
Dari PSR-2 2.2:
Unix LF (linefeed) line ending
.single blank line
.omitted
dari file yang berisionly php
Percayalah, mengikuti standar ini dapat menghemat banyak jam dari hidup Anda :)
sumber
?>
tag penutup dalam file apa pun dengan cara apa punCR LF
(khas Windows end of line). Saya menyelesaikannya dengan mengunduh file asli dari repo Wordpress yang memilikiLF
(Linux end of line) alih-alihCR LF
dan saya juga memindahkan fungsi saya ke fungsi theme.php. Berdasarkan pada: bit.ly/1Gh6mzN?>
<?php
, menghapus dan menambahkan satu baris kosong, menambahkan dan menghilangkan tag penutup?>
. Di Windows + Wamp, semua kombinasi itu berfungsi dengan baik. Wierd ...Kadang-kadang ketika proses dev memiliki stasiun kerja WIN dan sistem LINUX (hosting) dan dalam kode Anda tidak melihat output apa pun sebelum baris terkait, itu bisa berupa pemformatan file dan kurangnya akhiran baris UnFF LF (linefeed) berakhir .
Apa yang biasanya kita lakukan untuk memperbaikinya dengan cepat, adalah mengubah nama file dan pada sistem LINUX membuat file baru alih-alih yang diganti namanya, dan kemudian menyalin konten ke dalamnya. Sering kali ini memecahkan masalah karena beberapa file yang dibuat di WIN pernah dipindahkan ke hosting menyebabkan masalah ini.
Perbaikan ini adalah perbaikan yang mudah untuk situs yang kami kelola dengan FTP dan terkadang dapat menghemat waktu anggota tim baru kami.
sumber
Umumnya kesalahan ini muncul ketika kami mengirim tajuk setelah gema atau dicetak. Jika kesalahan ini muncul pada halaman tertentu maka pastikan halaman itu tidak menggemakan apa pun sebelum menelepon
start_session()
.Contoh Kesalahan Tidak Dapat Diprediksi:
Satu lagi contoh:
Kesimpulan: Jangan menampilkan karakter apa pun sebelum memanggil
session_start()
atauheader()
berfungsi bahkan bukan spasi putih atau baris barusumber