Rumah > Soal Jawab > teks badan
Apabila menjalankan skrip saya, saya mendapat beberapa ralat seperti ini:
Amaran: Tidak dapat mengubah suai maklumat pengepala - pengepala sudah dihantar oleh /some/file.php (Output bermula pada /some/file.php:12)
Barisan yang disebut dalam mesej ralat mengandungi panggilan header()
和 setcookie()
.
Apakah sebabnya? Bagaimana untuk menyelesaikannya?
P粉0716024062023-10-10 11:29:08
Hantar apa-apa sahaja sebelum menghantar pengepala HTTP (gunakan setcookie
或 header
). Sebab biasa untuk mengeluarkan sesuatu sebelum pengepala HTTP ialah:
Ruang yang tidak dijangka, biasanya pada permulaan atau penghujung fail, seperti ini:
Untuk mengelakkan perkara ini, tinggalkan sahaja pengakhiran ?>
- ia tidak diperlukan lagi.
3F 3C
开头。您可以安全地从文件开头删除 BOM EF BB BF
. echo
、printf
、readfile
、passthru
、 之前的代码>
dll. display_errors
display_errors
php.ini属性已设置。 php 不会因程序员错误而崩溃,而是默默地修复错误并发出警告。虽然您可以修改 display_errors
php.ini ditetapkan. Daripada ranap kerana ralat pengaturcara, php membetulkan ralat secara senyap dan mengeluarkan amaran. Walaupun anda boleh mengubah suai konfigurasi $_POST['input']
而不使用 empty
或 isset
进行测试是否设置了输入),或者使用未定义的常量而不是字符串文字(如 $_POST[input]
Sebab biasa ialah mengakses elemen yang tidak ditentukan dalam tatasusunan (cth. $_POST['input']
tanpa menggunakan kosong
isset
$_POST[input]
, perhatikan petikan yang tiada).
Hidupkan output bufferingob_start
后的所有输出都缓冲在内存中,直到您释放缓冲区,例如与 ob_end_flush
sepatutnya melakukan helah; semua output selepas memanggil ob_start
ob_end_flush
.
🎜Walau bagaimanapun, sementara penimbalan output boleh mengelakkan masalah ini, anda harus benar-benar menentukan sebab aplikasi anda mengeluarkan badan HTTP sebelum pengepala HTTP. Ia seperti menjawab telefon dan membincangkan hari anda dan cuaca, kemudian memberitahu pemanggil bahawa dia mendail nombor yang salah. 🎜P粉0879514422023-10-10 09:54:05
Sebelum sebarang output boleh dilakukan, fungsi yang menghantar/mengubah suai pengepala HTTP mesti dipanggil. Ringkasan⇊ Jika tidak, panggilan gagal:
Beberapa fungsi yang mengubah suai pengepala HTTP ialah:
标题
header_remove
/ header_remove
session_start
session_regenerate_id
/ session_regenerate_id
setcookie
setrawcookie
/ setrawcookie
Output boleh:
Tidak disengajakan:
之前或 ?>
Sengaja:
print
、echo
dan fungsi lain yang menghasilkan output 代码之前的原始
bahagian.
Adalah perlu untuk memahami mengapa pengepala mesti dihantar sebelum mengeluarkan Lihat tipikal HTTP balas. Skrip PHP terutamanya menjana kandungan HTML dan juga lulus a Set pengepala HTTP/CGI yang dihantar ke pelayan web:
HTTP/1.1 200 OK Powered-By: PHP/5.3.7 Vary: Accept-Encoding Content-Type: text/html; charset=utf-8PHP page output page Content
Some more output follows...
and
Halaman/Output sentiasa mengikut tajuk. PHP mesti lulus Mula-mula pengepala dihantar ke pelayan web. Ia hanya boleh melakukan ini sekali sahaja. Mereka tidak lagi boleh diubah suai selepas dua bungkus.
Apabila PHP menerima output pertama (print
、echo
、,
), ia akan
Segarkan semulasemua pengepala yang dikumpul. Selepas itu ia boleh menghantar semua output
Ia mahu. Tetapi menghantar pengepala HTTP selanjutnya tidak boleh dilakukan.
header()
Amaran mengandungi semua maklumat yang berkaitan
Punca masalah kedudukan:
Di sini "baris 100" merujuk kepada skrip yang header()
memanggil dan gagal.
Komen "output bermula pada " di dalam kurungan adalah lebih penting.
Ia mewakili sumber keluaran sebelumnya. Dalam contoh ini ialah auth.php
dan baris ke 52
. Di sinilah anda perlu mencari keluaran pramatang.
Sebab biasa:
print
和 echo
akan menamatkan peluang untuk menghantar pengepala HTTP. Proses permohonan mesti disusun semula untuk mengelakkan situasi ini. Menggunakan fungsi
dan penyelesaian templat. Pastikan panggilan header()
berlaku sebelum mesej
Semuanya sudah tertulis.
Fungsi yang menghasilkan output termasuk
打印
、echo
、printf
、vprintf
trigger_error
、ob_flush
、ob_end_flush
、var_dump
、print_r
readfile
、passthru
、flush
、imagepng
、imagejpeg
Dan fungsi lain dan ditakrifkan pengguna.
Bahagian HTML yang tidak dihuraikan dalam fail .php juga dikeluarkan secara langsung.
Seseorang mesti memberi perhatian kepada syarat skrip yang akan mencetuskan panggilan header()
Sebelum sebarang original blok.
Gunakan skema templat untuk memisahkan pemprosesan daripada logik output.
Ruang sebelum itu bermaksud "skrip.php Baris 1" amaran
Jika amaran merujuk kepada output sebaris1
, maka terutamanya
Memimpin ruang sebelum pembukaan tag, teks atau HTML.
Begitu juga ini boleh berlaku dengan skrip tambahan atau bahagian skrip:
?>PHP sebenarnya mengambil single line break selepas menutup tag. tetapi ia tidak akan Mengimbangi berbilang baris baharu, tab atau ruang yang dialihkan ke dalam jurang tersebut.
Barisan baharu dan ruang sahaja boleh menjadi masalah. Tetapi ada juga yang "tidak kelihatan"
Urutan watak yang boleh menyebabkan ini. Yang paling terkenal ialah
UTF-8 BOM (Tanda Pesanan Bait)
Kebanyakan penyunting teks tidak memaparkannya. Ia adalah urutan bait EF BB BF
,对于 UTF-8 编码的文档来说,它是可选且冗余的。然而 PHP 必须将其视为原始输出。它可能在输出中显示为字符 
(jika pelanggan mentafsir dokumen sebagai Latin-1) atau "sampah" yang serupa.
Terutama penyunting grafik dan IDE berasaskan Java tidak menyedarinya Hadir. Mereka tidak menggambarkannya (seperti yang dikehendaki oleh standard Unicode). Walau bagaimanapun, kebanyakan pengaturcara dan editor konsol akan:
Ini memudahkan untuk mengesan masalah lebih awal. Editor lain mungkin mengenali
Ia hadir dalam menu Fail/Tetapan (Notepad++ pada Windows mengenali dan
Selesai Masalah),
Pilihan lain untuk menyemak kewujudan BOM ialah menggunakan Hex Editor.
Pada sistem *nix hexdump
biasanya tersedia,
Jika tidak mudah menyemak variasi grafik soalan ini dan soalan lain:
Penyelesaian mudah ialah menetapkan editor teks anda untuk menyimpan fail sebagai "UTF-8 (tiada BOM)" Atau tatanama yang serupa. Selalunya pemula akan mengambil jalan keluar untuk mencipta fail baharu dan kemudian menyalin dan menampal semula kod sebelumnya.
Terdapat juga alatan automatik untuk menyemak dan menulis semula fail teks
(sed
/awk
sed
/awk代码>
或重新编码
atau recode
).
Untuk PHP, khususnya tag phptags
lebih kemas.
Ia menulis semula tag penutup dan pembukaan ke dalam bentuk panjang dan pendek dan juga mudah
Isu ruang hadapan dan belakang, Unicode dan UTF-x BOM:
phptags --whitespace *.php
Selamat digunakan pada keseluruhan termasuk atau direktori projek.
后有空格?>
Jika sumber ralat disebut kemudian
Tutup ?>
Di sinilah beberapa teks kosong atau mentah ditulis.
Teg penutup PHP tidak menamatkan pelaksanaan skrip pada masa ini. Sebarang aksara teks/ruang selepas itu akan ditulis sebagai kandungan halaman
masih.
Secara umumnya disyorkan, terutamanya untuk pemula, untuk mengikuti ?>
PHP
Teg penutup hendaklah ditinggalkan. Ini mengelakkan sebahagian kecil daripada kes ini.
(Skrip include()d
yang sangat biasa adalah puncanya.)
Jika tiada sumber ralat, ia biasanya sambungan PHP atau tetapan php.ini konkrit.
gzip
Tetapan pengekodan strim
atau ob_gzhandler
. extension=
Hasilkan mesej permulaan/amaran PHP tersirat. Jika pernyataan atau ungkapan PHP lain menyebabkan mesej amaran atau Nota dicetak, yang juga dikira sebagai output pramatang.
Dalam kes ini, anda perlu mengelakkan kesilapan,
Tangguhkan pelaksanaan kenyataan, atau sekat mesej menggunakan cth.
isset()
@()
atau @()
-
Apabila salah satu tidak menghalang penyahpepijatan kemudian.
Jika anda berdasarkan php.ini
禁用了 error_reporting
或 display_errors
,
Kemudian tiada amaran akan muncul. Tetapi mengabaikan ralat tidak menyelesaikan masalah
pergi. Masih tidak dapat menghantar pengepala selepas output pramatang.
Jadi apabila header("Location: ...")
ubah hala gagal secara senyap, ia sangat serius
Amaran siasatan adalah disyorkan. Dayakan semula mereka dengan dua arahan mudah
Di atas skrip panggilan:
error_reporting(E_ALL); ini_set("display_errors", 1);
atau set_error_handler("var_dump");
jika semuanya gagal.
Bercakap tentang pengepala ubah hala, anda harus sentiasa menggunakan simpulan bahasa seperti ini Ini ialah laluan kod terakhir:
exit(header("Location: /finished.html"));
Adalah yang terbaik untuk menjadi fungsi praktikal yang mencetak mesej pengguna
Jika header()
gagal.
PHP Penimbalan Output adalah penyelesaian untuk mengurangkan masalah ini. Ia biasanya berfungsi dengan pasti, tetapi tidak sepatutnya Gantikan struktur aplikasi yang betul dan keluarkan berasingan daripada kawalan logik. Tujuan sebenarnya adalah untuk meminimumkan pemindahan chunked ke pelayan web.
output_buffering=
Namun, tetapan membantu.
Konfigurasikannya dalam php.ini
Atau melalui .htaccess
Malah .user.ini
Persediaan FPM/FastCGI moden.
Mendayakan ini akan membolehkan PHP menimbal output dan bukannya menghantarnya ke pelayan web dengan segera. Oleh itu, PHP boleh mengagregat pengepala HTTP.
Ia juga boleh dipanggil dengan menelefon ob_start();
di atas skrip panggilan. Walau bagaimanapun, ia tidak begitu boleh dipercayai atas beberapa sebab:
Walaupun memulakan skrip pertama, ruang atau
BOM mungkin terbatal dan tidak sah sebelum render.
Ia boleh menyembunyikan ruang kosong output HTML. Walau bagaimanapun, sebaik sahaja logik aplikasi cuba menghantar kandungan binari (seperti imej yang dijana), Keluaran luar yang ditimbal menjadi masalah. (memerlukan ob_clean()) sebagai penyelesaian selanjutnya. )
Saiz penimbal adalah terhad dan mudah melimpah jika dibiarkan pada nilai lalai. Keadaan ini bukan perkara biasa, sukar untuk dikesan一个> apabila ia berlaku.
Oleh itu, kedua-dua kaedah boleh menjadi tidak boleh dipercayai - terutamanya apabila bertukar antara keduanya Persediaan pembangunan dan/atau pelayan pengeluaran. Inilah sebabnya mengapa penimbalan output adalah Secara meluas dianggap sebagai tongkat/penyelesaian yang ketat.
Lihat juga Contoh penggunaan asas Dalam manual, dan lebih banyak kebaikan dan keburukan:
Jika anda tidak mendapat amaran pengepala sebelum ini, penimbalan output tetapan php.ini sudah berubah. Ia mungkin tidak dikonfigurasikan pada pelayan semasa/baharu.
headers_sent()检查
Anda sentiasa boleh menggunakan headers_sent()
untuk mengesan jika
Masih boleh... untuk menghantar pengepala. Ini berguna untuk pencetakan bersyarat
maklumat atau gunakan logik sandaran lain.
if (headers_sent()) { die("Redirect failed. Please click on this link: "); } else{ exit(header("Location: /user.php")); }
Penyelesaian sandaran yang berguna ialah:
tagJika aplikasi anda secara struktur sukar untuk diperbaiki, maka yang mudah (tetapi
Agak tidak profesional) Cara untuk membenarkan pengalihan adalah dengan menyuntik HTML
Tag. Pengalihan boleh dicapai melalui:
Atau kelewatan singkat:
Ini mengakibatkan HTML tidak sah apabila digunakan di luar bahagian .
Kebanyakan pelayar masih menerimanya.
Sebagai alternatif, JavaScript ubah hala Tersedia untuk ubah hala halaman:
sssccc
Walaupun ini biasanya lebih mematuhi HTML daripada penyelesaian ,
Ia mengakibatkan pergantungan pada klien yang didayakan JavaScript.
Walau bagaimanapun, kedua-dua kaedah menghasilkan sandaran yang boleh diterima apabila pengepala HTTP sebenar() Panggilan gagal. Sebaik-baiknya, anda sentiasa menggabungkan ini dengan mesej mesra pengguna, Pautan boleh klik sebagai pilihan terakhir. (Sebagai contoh, http_redirect() Sambungan PECL tidak. )
setcookie()
和session_start()
juga terjejassetcookie()
和 session_start()
都需要发送 Set-Cookie:
Pengepala HTTP.
Oleh itu, syarat yang sama dikenakan dan mesej ralat yang serupa akan dihasilkan
Digunakan dalam kes pengeluaran pramatang.
(Sudah tentu, mereka juga dipengaruhi oleh melumpuhkan kuki dalam penyemak imbas anda Malah isu agensi. Ciri sesi jelas juga bergantung pada percuma Ruang cakera dan tetapan php.ini lain, dsb.)