Cara untuk Membetulkan Ralat "Tajuk Sudah Dihantar" dalam PHP
P粉210405394
P粉210405394 2023-10-09 21:06:28
0
2
452

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 panggilanheader()setcookie().

Apakah sebabnya? Bagaimana untuk menyelesaikannya?

P粉210405394
P粉210405394

membalas semua (2)
P粉071602406

Hantar apa-apa sahaja sebelum menghantar pengepala HTTP (gunakansetcookieheader). 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.

untuk menguji sama ada input ditetapkan), Atau gunakan pemalar yang tidak ditentukan dan bukannya literal rentetan (seperti dalam $_POST[input], perhatikan petikan yang tiada).

Hidupkanoutput bufferingob_start后的所有输出都缓冲在内存中,直到您释放缓冲区,例如与ob_end_flushsepatutnya melakukan helah; semua output selepas memanggilob_start

ditimbal dalam memori sehingga anda melepaskan penimbal, mis /ob_end_flush" rel="nofollow noreferrer"> 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粉087951442

    Tiada output sebelum menghantar tajuk!

    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:

    Output boleh:

    • Tidak disengajakan:

    • Sengaja:

      • printechodan fungsi lain yang menghasilkan output
      • 代码之前的原始bahagian.

    Mengapa ini berlaku?

    Adalah perlu untuk memahami mengapa pengepala mesti dihantar sebelum mengeluarkan Lihat tipikalHTTPbalas. 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 sentiasamengikuttajuk. 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 (printecho,), ia akanSegarkan semulasemua pengepala yang dikumpul. Selepas itu ia boleh menghantar semua output Ia mahu. Tetapi menghantar pengepala HTTP selanjutnya tidak boleh dilakukan.

    Bagaimana untuk mengetahui di mana pengeluaran pramatang berlaku?

    header()Amaran mengandungi semua maklumat yang berkaitan Punca masalah kedudukan:

    Di sini "baris 100" merujuk kepada skrip yangheader()memanggildan gagal.

    Komen "output bermula pada" di dalam kurungan adalah lebih penting. Ia mewakili sumber keluaran sebelumnya. Dalam contoh ini ialahauth.phpdanbaris ke52. Di sinilah anda perlu mencari keluaran pramatang.

    Sebab biasa:

    1. Cetak dan bergema

      Output yang disengajakan bagi pernyataan

      printechoakan menamatkan peluang untuk menghantar pengepala HTTP. Proses permohonan mesti disusun semula untuk mengelakkan situasi ini. Menggunakan fungsidan penyelesaian templat. Pastikan panggilanheader()berlaku sebelum mesejSemuanya sudah tertulis.

      Fungsi yang menghasilkan output termasuk

      • 打印echoprintfvprintf
      • trigger_errorob_flushob_end_flushvar_dumpprint_r
      • readfilepassthruflushimagepngimagejpeg


      Dan fungsi lain dan ditakrifkan pengguna.

    2. Kawasan HTML asal

      Bahagian HTML yang tidak dihuraikan dalam fail .php juga dikeluarkan secara langsung. Seseorang mesti memberi perhatian kepada syarat skrip yang akan mencetuskan panggilanheader()Sebelumsebarangoriginalblok.

                   

      Gunakan skema templat untuk memisahkan pemprosesan daripada logik output.

      • Letakkan kod pengendalian borang di atas skrip.
      • Gunakan pembolehubah rentetan sementara untuk menangguhkan mesej.
      • Logik output sebenar dan output HTML campuran hendaklah yang terakhir.

    3. Ruang sebelum itu bermaksud "skrip.phpBaris 1" amaran

      Jika amaran merujuk kepada output sebaris1, maka terutamanya Memimpin ruangsebelum pembukaantag, teks atau HTML.

                   

      Begitu juga ini boleh berlaku dengan skrip tambahan atau bahagian skrip:

      ?>
                    

      PHP sebenarnya mengambilsingleline break selepas menutup tag. tetapi ia tidak akan Mengimbangi berbilang baris baharu, tab atau ruang yang dialihkan ke dalam jurang tersebut.

    4. UTF-8 BOM

      Barisan baharu dan ruang sahaja boleh menjadi masalah. Tetapi ada juga yang "tidak kelihatan" Urutan watak yang boleh menyebabkan ini. Yang paling terkenal ialahUTF-8 BOM(Tanda Pesanan Bait)Kebanyakan penyunting teks tidak memaparkannya. Ia adalah urutan baitEF 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 danSelesai Masalah), Pilihan lain untuk menyemak kewujudan BOM ialah menggunakanHex Editor. Pada sistem *nixhexdumpbiasanya 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.

      Utiliti Pembetulan

      Terdapat juga alatan automatik untuk menyemak dan menulis semula fail teks (sed/awksed/awk代码>重新编码ataurecode). Untuk PHP, khususnya tagphptagslebih 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.

    5. 后有空格?>

      Jika sumber ralat disebut kemudianTutup?>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. Inimengelakkansebahagian kecil daripada kes ini. (Skripinclude()dyang sangat biasa adalah puncanya.)

    6. Punca ralat dipanggil "Barisan tidak diketahui 0"

      Jika tiada sumber ralat, ia biasanya sambungan PHP atau tetapan php.ini konkrit.

      • KadangkalagzipTetapan pengekodan strimatauob_gzhandler.
      • Tetapi ia juga boleh menjadi mana-mana modul dwi-muatextension=Hasilkan mesej permulaan/amaran PHP tersirat.

    7. Mesej ralat sebelumnya

      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() isset() @()atau@()- Apabila salah satu tidak menghalang penyahpepijatan kemudian.

    Tiada mesej ralat

    Jika anda berdasarkanphp.ini禁用了error_reportingdisplay_errors, Kemudian tiada amaran akan muncul. Tetapi mengabaikan ralat tidak menyelesaikan masalah pergi. Masih tidak dapat menghantar pengepala selepas output pramatang.

    Jadi apabilaheader("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);

    atauset_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 Jikaheader()gagal.

    Penimbalan output sebagai penyelesaian

    PHPPenimbalan Outputadalah 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.

    1. output_buffering=Namun, tetapan membantu. Konfigurasikannya dalamphp.iniAtau melalui.htaccessMalah.user.iniPersediaan 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.

    2. Ia juga boleh dipanggil dengan menelefonob_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 sebelumrender.

      • 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 jugaContoh penggunaan asasDalam manual, dan lebih banyak kebaikan dan keburukan:

    Tetapi ia berfungsi pada pelayan lain! ?

    Jika anda tidak mendapat amaran pengepala sebelum ini,penimbalan output tetapan php.inisudah berubah. Ia mungkin tidak dikonfigurasikan pada pelayan semasa/baharu.

    Gunakanheaders_sent()检查

    Anda sentiasa boleh menggunakanheaders_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:

    • HTML tag

      Jika 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.

    • JavaScript Redirect

      Sebagai alternatif,JavaScript ubah halaTersedia 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. )

    Kenapasetcookie()session_start()juga terjejas

    setcookie()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.)

    Lagi pautan

      Muat turun terkini
      Lagi>
      kesan web
      Kod sumber laman web
      Bahan laman web
      Templat hujung hadapan
      Tentang kita Penafian Sitemap
      Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!