Sarlavhalarni yuborishdan oldin chiqish yo'q!
HTTP sarlavhalarini yuboruvchi/o'zgartiruvchi funksiyalarhar qanday chiqishdan oldinchaqirilishi kerak. xulosa ⇊ Aks holda qo‘ng‘iroq bajarilmaydi:
Ogohlantirish: Sarlavha maʼlumotlarini oʻzgartirib boʻlmaydi – sarlavhalar allaqachon yuborilgan (chiqish script:line da boshlangan)
HTTP sarlavhasini o'zgartiruvchi ba'zi funktsiyalar:
Chiqish bo'lishi mumkin:
Qasddan:
print
, echo
and other functions producing output
<?php
kodidan oldingi <html>
bo'lim.
Nima uchun bu sodir bo'ladi?
Nima uchun sarlavhalar chiqishdan oldin yuborilishi kerakligini tushunish uchun odatdagi HTTP javobini ko'rib chiqish kerak. PHP skriptlari asosan HTML kontentini yaratadi, lekin HTTP/CGI sarlavhalari toʻplamini veb-serverga uzatadi:
HTTP/1.1 200 OK
Powered-By: PHP/5.3.7
Vary: Accept-Encoding
Content-Type: text/html; charset=utf-8
<html><head><title>PHP page output page</title></head>
<body><h1>Content</h1> <p>Some more output follows...</p>
and <a href="/"> <img src=internal-icon-delayed> </a>
Sahifa/chiqish har doim sarlavhalardan kuzatib boradi. PHP avval sarlavhalarni veb-serverga o'tkazishi kerak. Buni faqat bir marta qilish mumkin. Ikki qatorli uzilishdan keyin u ularni hech qachon o'zgartira olmaydi.
PHP birinchi chiqishni qabul qilganda (print
, echo
, <html>
) barcha yigʻilgan sarlavhalarni tozalaydi. Shundan so'ng u barcha kerakli natijalarni yuborishi mumkin. Ammo keyin boshqa HTTP sarlavhalarini yuborish mumkin emas.
Erta chiqish qaerda sodir bo'lganligini qanday aniqlash mumkin?
header()
ogohlantirish muammo sababini aniqlash uchun barcha tegishli ma'lumotlarni o'z ichiga oladi:
Ogohlantirish: Sarlavha ma'lumotlarini o'zgartirib bo'lmaydi - sarlavhalar allaqachon tomonidan yuborilgan(chiqaruv /www/usr2345/htdocs/auth.php:52da boshlangan) /www/usr2345/htdocs/index.php 100-qatorda
Bu erda 100-qator header()
chaqiruv muvaffaqiyatsiz bo'lgan skriptga ishora qiladi.
Qavs ichidagi chiqishda boshlangan yozuv muhimroq. Bu avvalgi ishlab chiqarish manbasini ko'rsatadi. Bu misolda bu auth.php
va satr 52
. Bu erda siz erta chiqishni izlashingiz kerak edi.
Odat sabablari:
Chop etish, aks-sado
print
va echo
bayonotlaridan ataylab chiqish HTTP sarlavhalarini yuborish imkoniyatini to'xtatadi. Bunga yo'l qo'ymaslik uchun dastur oqimi qayta tuzilishi kerak. funksiyalar va shablon sxemalaridan foydalaning. Xabarlar yozilishidan oldin header()
qo'ng'iroqlar sodir bo'lishiga ishonch hosil qiling.
Chiqarish ishlab chiqaradigan funktsiyalar kiradi
print
, echo
, printf
, vprintf
trigger_error
, ob_flush
, ob_end_flush
, var_dump
, print_r
readfile
, passthru
, flush
, imagepng
, imagejpeg
boshqalar va foydalanuvchi tomonidan belgilangan funktsiyalar.
Raw HTML hududlari
.php
faylidagi tahlil qilinmagan HTML bo'limlari ham bevosita chiqariladi. header()
chaqiruvini ishga tushiradigan skript shartlari har qanday xom <html>
bloklaridan oldin qayd etilishi kerak.
<!DOCTYPE html>
<?php
// Too late for headers already.
Chiqish mantig'idan ishlov berishni ajratish uchun shablonlash sxemasidan foydalaning.
- Place form processing code atop scripts.
- Xabarlarni kechiktirish uchun vaqtinchalik string o'zgaruvchilardan foydalaning.
- Haqiqiy chiqish mantig'i va aralash HTML chiqishi oxirgi bo'lishi kerak.
script.php 1-qator ogohlantirishlari uchun <?php
oldidan boʻsh joy
Agar ogohlantirish 1
qatoridagi chiqishga tegishli boʻlsa, u asosan ochilish <?php
belgisi oldidagi boʻsh joy, matn yoki HTMLga olib keladi.
<?php
# There's a SINGLE space/newline before <? - Which already seals it.
Xuddi shunday, qo'shilgan skriptlar yoki skript bo'limlari uchun ham sodir bo'lishi mumkin:
?>
<?php
PHP aslida teglarni yopishdan so'ng bitta qator uzilishini yeydi. Ammo u bir nechta yangi qatorlar yoki yorliqlar yoki bunday bo'shliqlarga o'tkazilgan bo'shliqlarni qoplamaydi.
- #P64# #P23# #P24# #P25# #P26# #P65# #P27#
phptags --whitespace *.php
#P28#
?>
dan keyin boʻsh joy
Agar xato manbasi yopilish ?>
orqasida aytilgan bo'lsa, bu erda bo'sh joy yoki xom matn paydo bo'ladi. yozilgan. PHP yakuniy belgisi bu nuqtada skriptning bajarilishini to'xtatmaydi. Undan keyingi har qanday matn/boʻsh joy hali ham sahifa mazmuni sifatida yoziladi.
Odatda, ayniqsa, yangi kelganlarga, keyingi ?>
PHP yopish teglaridan voz kechish tavsiya etiladi. Bu ushbu holatlarning kichik qismini eslatadi. (Ko'pincha include()d
skriptlar aybdor.)
0-qatorda noma'lum deb qayd etilgan xato manbasi
Agar xato manbasi aniqlanmagan bo'lsa, bu odatda PHP kengaytmasi yoki php.ini sozlamasidir.
- It's occasionally the
gzip
stream encoding setting
or the ob_gzhandler
.
- Lekin bu, shuningdek, PHP ni ishga tushirish/ogohlantirish xabarini ishlab chiqaruvchi har qanday ikki marta yuklangan
extension=
moduli ham boʻlishi mumkin.
Oldingi xato xabarlari
Agar boshqa PHP bayonoti yoki ifodasi ogohlantirish xabari yoki bildirishnomaning chop etilishiga sabab bo'lsa, bu ham muddatidan oldin chiqarilgan deb hisoblanadi.
Bunday holda siz xatodan qochishingiz, bayonotning bajarilishini kechiktirishingiz yoki xabarni bosishingiz kerak. isset()
yoki @()
< /a> - keyinchalik nosozliklarni tuzatishga to'sqinlik qilmasa.
Xato xabari yoʻq
Agar sizda php.ini
uchun error_reporting
yoki display_errors
o'chirilgan bo'lsa, hech qanday ogohlantirish ko'rsatilmaydi. Ammo xatolarga e'tibor bermaslik muammoni hal qilmaydi. Sarlavhalarni muddatidan oldin chiqqandan keyin ham yuborish mumkin emas.
Shunday qilib, header("Location: ...")
yo'naltirishlari jimgina bajarilmasa, ogohlantirishlarni tekshirish tavsiya etiladi. Chaqiruv skripti ustidagi ikkita oddiy buyruq bilan ularni qayta yoqing:
error_reporting(E_ALL);
ini_set("display_errors", 1);
Yoki hammasi bajarilmasa set_error_handler("var_dump");
.
Qayta yo'naltirish sarlavhalari haqida gapiradigan bo'lsak, siz ko'pincha oxirgi kod yo'llari uchun shunday idiomadan foydalanishingiz kerak:
exit(header("Location: /finished.html"));
Hatto header()
xatolik yuz berganda foydalanuvchi xabarini chop etadigan yordamchi funksiya ham afzalroq.
Vaqtinchalik yechim sifatida chiqish buferi
PHP chiqishni buferlash bu muammoni bartaraf etishning vaqtinchalik yechimidir. U ko'pincha ishonchli ishlaydi, lekin dasturni to'g'ri tuzish va chiqishni boshqarish mantig'idan ajratish o'rnini bosa olmaydi. Uning asl maqsadi veb-serverga bo'lakli o'tkazmalarni minimallashtirishdir.
Shunga qaramay, output_buffering=
sozlamasi yordam berishi mumkin. Uni php.ini yoki .htaccess yoki hatto .user.ini zamonaviy FPM/FastCGI sozlamalarida.
Uni yoqish PHP-ga chiqishni veb-serverga o'tkazish o'rniga buferlash imkonini beradi. darhol. Shunday qilib, PHP HTTP sarlavhalarini to'plashi mumkin.
Uni chaqirish skripti tepasida ob_start();
ga qo‘ng‘iroq qilish ham mumkin. Biroq, bu bir nechta sabablarga ko'ra kamroq ishonchli:
<?php ob_start(); ?>
birinchi skriptni ishga tushirsa ham, bo'sh joy yoki BOM avval aralashib ketishi mumkin, uni samarasiz qilish.
U HTML chiqishi uchun bo'sh joyni yashirishi mumkin. Ammo dastur mantig'i ikkilik tarkibni (masalan, yaratilgan rasm) yuborishga harakat qilishi bilanoq, buferlangan tashqi chiqish muammoga aylanadi. (Yana vaqtinchalik yechim sifatida ob_clean()
talab qilinadi.)
Bufer hajmi cheklangan va sukut bo'yicha qoldirilganda osongina oshib ketishi mumkin. Va bu ham kamdan-kam uchraydigan hodisa emas, ta'qib qilish qiyin a> bu sodir bo'lganda.
Shuning uchun ikkala yondashuv ham ishonchsiz bo'lib qolishi mumkin, xususan, ishlab chiqish sozlamalari va/yoki ishlab chiqarish serverlari o'rtasida almashishda. Shuning uchun chiqishni buferlash keng tarqalgan bo'lib faqat qo'ltiq tayoqchasi/qat'iy vaqtinchalik yechim deb hisoblanadi.
Shuningdek, qoʻllanmadagi asosiy foydalanish misoliga va boshqalarga qarang. ijobiy va salbiy tomonlari:
Lekin u boshqa serverda ishlagan!?
Agar siz avval sarlavhalar haqida ogohlantirish olmagan boʻlsangiz, u holda php.ini chiqish buferlash sozlamasini tanlang. a> o'zgargan. Joriy/yangi serverda sozlanmagan.
headers_sent()
bilan tekshirilmoqda
Sarlavhalarni yuborishingiz mumkinmi yoki yoʻqligini tekshirish uchun har doim headers_sent()
dan foydalanishingiz mumkin. Bu ma'lumotni shartli chop etish yoki boshqa qayta mantiqni qo'llash uchun foydalidir.
if (headers_sent()) {
die("Redirect failed. Please click on this link: <a href=...>");
}
else{
exit(header("Location: /user.php"));
}
Qayta tiklashning foydali echimlari quyidagilardir:
HTML <meta>
tegi
Agar ilovangizni tizimli ravishda tuzatish qiyin bo'lsa, qayta yo'naltirishga ruxsat berishning oson (lekin biroz noprofessional) usuli HTML <meta>
tegini kiritishdir. Qayta yo'naltirishga quyidagilar orqali erishish mumkin:
<meta http-equiv="Location" content="http://example.com/">
Yoki qisqa kechikish bilan:
<meta http-equiv="Refresh" content="2; url=../target.html">
Bu <head>
bo'limidan keyin foydalanilganda noto'g'ri HTMLga olib keladi. Ko'pgina brauzerlar buni hali ham qabul qilishadi.
JavaScript-ni qayta yo'naltirish
Muqobil sifatida JavaScript-ni qayta yo'naltirish dan foydalanish mumkin. sahifani qayta yo'naltirish uchun:
<script> location.replace("target.html"); </script>
Bu ko'pincha <meta>
vaqtinchalik hal qilishdan ko'ra ko'proq HTMLga mos keladigan bo'lsa-da, u JavaScript-ni qo'llab-quvvatlaydigan mijozlarga tayanadi.
Haqiqiy HTTP sarlavhasi() qo'ng'iroqlari muvaffaqiyatsiz bo'lsa, ikkala yondashuv ham qabul qilinadigan zaxiralarni yaratadi. Ideal holda siz buni har doim oxirgi chora sifatida foydalanuvchilarga qulay xabar va bosiladigan havola bilan birlashtirasiz. (Masalan, http://php.net/http_redirect PECL kengaytmasi nima qiladi.)
Nima uchun setcookie()
va session_start()
ham ta'sir qiladi
setcookie()
va session_start()
ham Set-Cookie:
HTTP sarlavhasini yuborishi kerak. Shuning uchun bir xil shartlar qo'llaniladi va shunga o'xshash xato xabarlari muddatidan oldin chiqish holatlari uchun yaratiladi.
(Albatta, ularga brauzerda o‘chirilgan cookie-fayllar yoki hatto proksi-server bilan bog‘liq muammolar ham ta’sir qiladi. Seans funksiyasi, albatta, bo‘sh disk maydoni va boshqa php.ini sozlamalari va hokazolarga bog‘liq.)
Qo'shimcha havolalar
person
mario
schedule
06.11.2011
ob_start
vaob_end_clean()
bu yerda foydali boʻlishi mumkin). Keyinob_get_contents()
ga teng cookie yoki seans o'rnatishingiz va keyin buferni tozalash uchunob_end_clean()
dan foydalanishingiz mumkin. - person Jack   schedule 04.04.2014safeRedirect
funksiyasidan foydalaning: github.com/heinkasner/PHP -Library/blob/master/extra.php - person heinkasner   schedule 24.07.2014UTF-8
bo'lmasligi kerak, lekinUTF-8 (Without BOM)
~~~~~~~~~~~ - person T.Todua   schedule 19.09.2014