हेडर भेजने से पहले कोई आउटपुट नहीं!
किसी भी आउटपुट के आने से पहले HTTP हेडर भेजने / संशोधित करने वाले कार्य किए जाने चाहिए ।
summary ⇊
अन्यथा कॉल विफल:
चेतावनी: शीर्ष लेख की सूचना को संशोधित नहीं किया जा सकता - हेडर पहले से ही भेजा गया (आउटपुट स्क्रिप्ट पर शुरू हुआ : पंक्ति )
HTTP हेडर को संशोधित करने वाले कुछ कार्य हैं:
आउटपुट हो सकता है:
जानबूझकर:
print
, echo
और अन्य उत्पादन उत्पादन कार्य करता है
- कच्चा
<html>
अनुभाग पूर्व <?php
कोड।
क्यों होता है?
यह समझने के लिए कि आउटपुट से पहले हेडर क्यों भेजा जाना चाहिए, यह एक विशिष्ट HTTP
प्रतिक्रिया को देखने के लिए आवश्यक है । PHP स्क्रिप्ट मुख्य रूप से HTML सामग्री उत्पन्न करती है, लेकिन वेबसर्वर के लिए HTTP / CGI हेडर का एक सेट भी पास करती है:
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>
पेज / आउटपुट हमेशा हेडर का अनुसरण करता है। PHP को सबसे पहले वेबसर्वर को हेडर पास करना होता है। यह केवल एक बार ही कर सकता है। डबल लाइनब्रेक के बाद यह कभी भी उन्हें संशोधित नहीं कर सकता है।
जब पीएचपी पहले उत्पादन प्राप्त करता है ( print
, echo
, <html>
) यह होगा
फ्लश सभी एकत्र हेडर। बाद में यह सभी आउटपुट भेज सकता है। लेकिन इसके बाद HTTP हेडर भेजना असंभव है।
आप यह कैसे पता लगा सकते हैं कि समय से पहले उत्पादन कैसे हुआ?
header()
चेतावनी समस्या कारण का पता लगाने के लिए सभी प्रासंगिक जानकारी होती है:
चेतावनी: शीर्ष लेख की सूचना को संशोधित नहीं किया जा सकता - हेडर पहले से ही भेजे गए
(आउटपुट / www / usr2345 / htdocs / schem.php पर शुरू हुआ ) : 52 / / /r2345/htdocs/index.php पर लाइन 100 पर
यहां "लाइन 100" उस स्क्रिप्ट को संदर्भित करता है जहां header()
मंगलाचरण विफल रहा।
कोष्ठक के भीतर " आउटपुट शुरू " नोट अधिक महत्वपूर्ण है। यह पिछले आउटपुट के स्रोत को दर्शाता है। इस उदाहरण में यह auth.php
और लाइन है52
। यहीं आपको समय से पहले आउटपुट के लिए देखना था।
विशिष्ट कारण:
प्रिंट, गूंज
से प्रासंगिक आउटपुट print
और echo
स्टेटमेंट HTTP हेडर भेजने का अवसर समाप्त कर देंगे। उससे बचने के लिए एप्लिकेशन प्रवाह का पुनर्गठन किया जाना चाहिए। कार्यों
और अस्थायी योजनाओं का उपयोग करें । संदेश लिखे जाने से पहले सुनिश्चित करें कि header()
कॉल हो ।
आउटपुट का उत्पादन करने वाले कार्यों में शामिल हैं
print
, echo
, printf
,vprintf
trigger_error
, ob_flush
, ob_end_flush
, var_dump
,print_r
readfile
, passthru
, flush
, imagepng
,imagejpeg
दूसरों और उपयोगकर्ता-परिभाषित कार्यों के बीच।
कच्चे HTML क्षेत्रों
किसी .php
फ़ाइल में अनपर्स किए गए HTML सेक्शन भी सीधे आउटपुट होते हैं। किसी भी कच्चे ब्लॉक header()
से पहले कॉल को ट्रिगर करने वाली स्क्रिप्ट शर्तों को नोट किया जाना चाहिए ।<html>
<!DOCTYPE html>
<?php
// Too late for headers already.
आउटपुट लॉजिक से प्रसंस्करण को अलग करने के लिए एक अस्थायी योजना का उपयोग करें।
- स्क्रिप्ट कोड के रूप में जगह प्रसंस्करण कोड।
- संदेशों को स्थगित करने के लिए अस्थायी स्ट्रिंग चर का उपयोग करें।
- वास्तविक आउटपुट लॉजिक और इंटरमिक्स किए गए HTML आउटपुट को अंतिम अनुसरण करना चाहिए।
<?php
"Script.php लाइन 1 " चेतावनी के लिए पहले व्हाट्सएप
यदि चेतावनी लाइन में आउटपुट को संदर्भित करती है 1
, तो यह शुरुआती टोकन से पहले ज्यादातर व्हाट्सएप , टेक्स्ट या HTML का नेतृत्व कर रहा है <?php
।
<?php
# There's a SINGLE space/newline before <? - Which already seals it.
इसी तरह यह संलग्न लिपियों या स्क्रिप्ट अनुभागों के लिए हो सकता है:
?>
<?php
PHP वास्तव में करीबी टैग के बाद एक ही लाइनब्रेक खाती है । लेकिन यह इस तरह के अंतराल में स्थानांतरित कई नए समाचार या टैब या रिक्त स्थान की भरपाई नहीं करेगा।
UTF-8 BOM
अकेले लाइनब्रेक और रिक्त स्थान एक समस्या हो सकती है। लेकिन "अदृश्य" चरित्र अनुक्रम भी हैं जो इसका कारण बन सकते हैं। सबसे प्रसिद्ध
UTF-8 BOM (बाइट-ऑर्डर-मार्क)
जो अधिकांश टेक्स्ट संपादकों द्वारा प्रदर्शित नहीं किया जाता है। यह बाइट अनुक्रम है EF BB BF
, जो UTF-8 एन्कोडेड दस्तावेज़ों के लिए वैकल्पिक और निरर्थक है। PHP को हालांकि इसे कच्चा आउटपुट माना जाता है। यह 
आउटपुट में पात्रों के रूप में दिखाई दे सकता है (यदि क्लाइंट दस्तावेज़ को लैटिन -1 के रूप में व्याख्या करता है) या इसी तरह के "कचरा" के रूप में।
विशेष रूप से चित्रमय संपादकों और जावा आधारित IDE इसकी उपस्थिति से बेखबर हैं। वे इसकी कल्पना नहीं करते (यूनिकोड मानक द्वारा बाध्य)। अधिकांश प्रोग्रामर और कंसोल एडिटर हालांकि करते हैं:
समस्या को जल्दी पहचानना आसान है। अन्य संपादकों एक फ़ाइल / सेटिंग्स मेनू में अपनी उपस्थिति की पहचान (Notepad ++ विंडोज पर पहचान करने और कर सकते हैं हो सकता है
समस्या का समाधान BOMs उपस्थिति एक का सहारा है निरीक्षण करने के लिए एक अन्य विकल्प), hexeditor । पर * निक्स सिस्टम hexdump
आमतौर पर उपलब्ध होता है, यदि ग्राफिकल वैरिएंट नहीं है जो इन और अन्य मुद्दों की ऑडिटिंग को सरल बनाता है:
फ़ाइलों को "UTF-8 (कोई BOM)" या इस तरह के नामकरण के रूप में सहेजने के लिए पाठ संपादक को सेट करने के लिए एक आसान निर्धारण है। अक्सर नए लोग नई फाइल बनाने का सहारा लेते हैं और पिछले कोड को वापस कॉपी करके चिपका देते हैं।
सुधार उपयोगिताओं
टेक्स्ट फ़ाइलों ( sed
/awk
या recode
) को जांचने और फिर से लिखने के लिए स्वचालित उपकरण भी हैं । PHP के लिए विशेष रूप से वहाँ phptags
टैग tidier है । यह लंबे और छोटे रूपों में नज़दीकी और खुले टैग्स को फिर से लिखता है, लेकिन व्हाट्सएप, यूनिकोड और यूटीएफ-एक्स बीओएम मुद्दों को आसानी से ले जाता है।
phptags --whitespace *.php
यह पूरी तरह से शामिल या परियोजना निर्देशिका पर उपयोग करने के लिए समझदार है।
व्हाट्सएप के बाद ?>
यदि समापन के?>
पीछे त्रुटि स्रोत का उल्लेख किया गया है,
तो यह वह जगह है जहां कुछ व्हाट्सएप या कच्चे पाठ को लिखा गया है। PHP अंत मार्कर इस बिंदु पर स्क्रिप्ट निष्पादन को समाप्त नहीं करता है। किसी भी पाठ / अंतरिक्ष वर्ण के बाद इसे पृष्ठ सामग्री के रूप में लिखा जाएगा।
यह आमतौर पर सलाह दी जाती है, विशेष रूप से नए लोगों के लिए, कि अनुगामी ?>
PHP क्लोज टैग को छोड़ दिया जाना चाहिए। इससे इन मामलों का एक छोटा सा हिस्सा बच जाता है। (काफी सामान्य include()d
स्क्रिप्ट अपराधी हैं।)
त्रुटि स्रोत "अज्ञात लाइन 0 पर" के रूप में वर्णित
यह आमतौर पर एक PHP विस्तार या php.ini सेटिंग है यदि कोई त्रुटि स्रोत समवर्ती नहीं है।
- यह कभी-कभी
gzip
स्ट्रीम एन्कोडिंग सेटिंग
या हैob_gzhandler
।
- लेकिन यह कोई भी दोगुना लोडेड
extension=
मॉड्यूल हो सकता है जो एक अंतर्निहित PHP स्टार्टअप / चेतावनी संदेश उत्पन्न करता है।
पूर्ववर्ती त्रुटि संदेश
यदि कोई अन्य PHP स्टेटमेंट या एक्सप्रेशन एक चेतावनी संदेश या नोटिस को प्रिंट आउट होने का कारण बनता है, तो वह समय से पहले आउटपुट के रूप में भी गिना जाता है।
इस मामले में आपको त्रुटि से बचने, कथन के निष्पादन में देरी करने, या उदाहरण के साथ संदेश को दबाने
isset()
या @()
- जब या तो बाद में डीबगिंग में बाधा नहीं आती है।
कोई त्रुटि संदेश नहीं
यदि आपके पास error_reporting
या display_errors
प्रति अक्षम है php.ini
, तो कोई चेतावनी नहीं दिखाई देगी। लेकिन त्रुटियों को अनदेखा करने से समस्या दूर नहीं होगी। समय से पहले आउटपुट के बाद भी हेडर नहीं भेजे जा सकते हैं।
इसलिए जब header("Location: ...")
रीडायरेक्ट चुपचाप विफल हो जाते हैं तो चेतावनी के लिए जांच करना बहुत उचित है। दो सरल आदेशों के साथ उन्हें फिर से मंगवाएं, जो कि इनवोकेशन स्क्रिप्ट के ऊपर हैं:
error_reporting(E_ALL);
ini_set("display_errors", 1);
या set_error_handler("var_dump");
अगर बाकी सब विफल रहता है।
रीडायरेक्ट हेडर की बात करते हुए, आपको अक्सर अंतिम कोड पथ के लिए इस तरह से एक मुहावरे का उपयोग करना चाहिए:
exit(header("Location: /finished.html"));
अधिमानतः एक उपयोगिता फ़ंक्शन, जो header()
विफलताओं के मामले में एक उपयोगकर्ता संदेश प्रिंट करता है ।
आउटपुट बफ़रिंग को वर्कअराउंड के रूप में
PHPs आउटपुट बफ़रिंग
इस समस्या को कम करने के लिए एक समाधान है। यह अक्सर मज़बूती से काम करता है, लेकिन उचित अनुप्रयोग संरचना और नियंत्रण तर्क से आउटपुट को अलग करने के लिए स्थानापन्न नहीं होना चाहिए। इसका वास्तविक उद्देश्य वेबसर्वर के लिए स्थानांतरित स्थान को कम करना है।
output_buffering=
सेटिंग फिर भी कर सकते हैं। इसे आधुनिक FPM / FastCGP सेटअप पर php.ini
या .htaccess
या even .user.ini में कॉन्फ़िगर करें ।
इसे सक्षम करना PHP को वेबसर्वर पर तुरंत पारित करने के बजाय बफर आउटपुट के लिए अनुमति देगा। PHP इस प्रकार HTTP हेडर एकत्रित कर सकता है।
यह वैसे ही ob_start();
आह्वान स्क्रिप्ट के ऊपर कॉल के साथ संलग्न किया जा सकता है । हालांकि कई कारणों से कम विश्वसनीय है:
यहां तक कि अगर <?php ob_start(); ?>
पहली स्क्रिप्ट शुरू होती है, तो व्हाट्सएप या बीओएम अप्रभावी होने से पहले ही फेरबदल कर सकता है ।
यह HTML आउटपुट के लिए व्हॉट्सएप छुपा सकता है। लेकिन जैसे ही एप्लिकेशन लॉजिक बाइनरी कंटेंट (उदाहरण के लिए एक उत्पन्न हुई छवि) को भेजने का प्रयास करता है, बफ़र किए गए एक्सट्रॉन्स आउटपुट एक समस्या बन जाता है। ( ob_clean()
फरारी वर्कअराउंड के रूप में आवश्यक।)
बफर आकार में सीमित है, और आसानी से चूक के लिए छोड़ दिया जा सकता है। और यह एक दुर्लभ घटना भी नहीं है,
ऐसा होने पर नीचे ट्रैक करना मुश्किल है।
इसलिए दोनों दृष्टिकोण अविश्वसनीय हो सकते हैं - विशेष रूप से जब विकास सेटअप और / या उत्पादन सर्वर के बीच स्विच करते हैं। यही कारण है कि आउटपुट बफ़रिंग को व्यापक रूप से सिर्फ एक बैसाखी / सख्ती से वर्कअराउंड माना जाता है।
मैनुअल में मूल उपयोग उदाहरण भी देखें , और अधिक पेशेवरों और विपक्षों के लिए:
लेकिन यह दूसरे सर्वर पर काम किया !?
यदि आपको पहले हेडर चेतावनी नहीं मिली है, तो आउटपुट बफरिंग php.ini सेटिंग
बदल गई है। यह वर्तमान / नए सर्वर पर अपुष्ट होने की संभावना है।
के साथ जाँच कर रहा है headers_sent()
आप हमेशा headers_sent()
जांच करने के लिए उपयोग कर सकते हैं कि क्या यह अभी भी संभव है ... हेडर भेजें। जो सशर्त रूप से किसी जानकारी को प्रिंट करने या अन्य कमबैक तर्क को लागू करने के लिए उपयोगी है।
if (headers_sent()) {
die("Redirect failed. Please click on this link: <a href=...>");
}
else{
exit(header("Location: /user.php"));
}
उपयोगी कमियां हैं:
HTML <meta>
टैग
यदि आपका एप्लिकेशन ठीक करने के लिए संरचनात्मक रूप से कठिन है, तो रीडायरेक्ट करने की अनुमति देने का एक आसान (लेकिन कुछ हद तक लाभहीन) तरीका HTML <meta>
टैग को इंजेक्ट कर रहा है
। एक पुनर्निर्देशन के साथ प्राप्त किया जा सकता है:
<meta http-equiv="Location" content="http://example.com/">
या एक छोटी देरी के साथ:
<meta http-equiv="Refresh" content="2; url=../target.html">
यह पिछले <head>
अनुभाग में उपयोग किए जाने पर गैर-वैध HTML की ओर जाता है । अधिकांश ब्राउज़र अभी भी इसे स्वीकार करते हैं।
जावास्क्रिप्ट पुनर्निर्देशित
विकल्प के रूप में जावास्क्रिप्ट पुनर्निर्देशन
का उपयोग पृष्ठ पुनर्निर्देश के लिए किया जा सकता है:
<script> location.replace("target.html"); </script>
जबकि यह अक्सर <meta>
वर्कअराउंड की तुलना में अधिक HTML अनुरूप है , यह जावास्क्रिप्ट-सक्षम ग्राहकों पर निर्भरता को बढ़ाता है।
हालाँकि वास्तविक HTTP शीर्ष लेख () कॉल विफल होने पर दोनों दृष्टिकोण स्वीकार्य कमियां बनाते हैं। आदर्श रूप से आप इसे हमेशा अंतिम विकल्प के रूप में उपयोगकर्ता के अनुकूल संदेश और क्लिक करने योग्य लिंक के साथ जोड़ेंगे। (उदाहरण के लिए जो http_redirect ()
PECL एक्सटेंशन करता है।)
क्यों setcookie()
और session_start()
कैसे प्रभावित होते हैं
दोनों setcookie()
और session_start()
एक Set-Cookie:
HTTP हेडर भेजने की जरूरत है । इसलिए वही स्थितियाँ लागू होती हैं, और समयपूर्व आउटपुट स्थितियों के लिए समान त्रुटि संदेश उत्पन्न होंगे।
(बेशक वे ब्राउज़र में अक्षम कुकीज़ से प्रभावित होते हैं, या यहां तक कि प्रॉक्सी के मुद्दे। सत्र की कार्यक्षमता स्पष्ट रूप से मुक्त डिस्क स्थान और अन्य php.ini सेटिंग्स, आदि पर भी निर्भर करती है)
आगे के लिंक