PHP में HTTP_HOST और SERVER_NAME के बीच क्या अंतर है?




apache server-variables (6)

आप एक दूसरे पर एक का उपयोग करने पर विचार क्यों करेंगे और क्यों?


अगर आप server.php से जांचना चाहते हैं या आप इसे निम्न के साथ कभी भी कॉल करना चाहते हैं:

<?php

phpinfo(INFO_VARIABLES);

?>

या

<?php

header("Content-type: text/plain");

print_r($_SERVER);

?>

फिर अपनी साइट के लिए सभी मान्य यूआरएल के साथ इसका उपयोग करें और अंतर देखें।


कृपया ध्यान दें कि यदि आप आईपीवी 6 का उपयोग करना चाहते हैं, तो आप शायद SERVER_NAME बजाय HTTP_HOST का उपयोग करना चाहते हैं। यदि आप http://[::1]/ पर्यावरण चर बदलते हैं तो निम्न होंगे:

HTTP_HOST = [::1]
SERVER_NAME = ::1

इसका मतलब यह है कि, यदि आप उदाहरण के लिए mod_rewrite करते हैं, तो आपको एक बुरा परिणाम मिल सकता है। एसएसएल रीडायरेक्ट के लिए उदाहरण:

# SERVER_NAME will NOT work - Redirection to https://::1/
RewriteRule .* https://%{SERVER_NAME}/

# HTTP_HOST will work - Redirection to https://[::1]/
RewriteRule .* https://%{HTTP_HOST}/

यह केवल तभी लागू होता है जब आप होस्टनाम के बिना सर्वर तक पहुंचते हैं।


जैसा कि मैंने इस उत्तर में उल्लेख किया है, यदि सर्वर 80 से अधिक पोर्ट (जैसा कि विकास / इंट्रानेट मशीन पर आम हो सकता है) तो HTTP_HOST में पोर्ट होता है, जबकि SERVER_NAME नहीं करता है।

$_SERVER['HTTP_HOST'] == 'localhost:8080'
$_SERVER['SERVER_NAME'] == 'localhost'

(कम से कम यही है जो मैंने अपाचे पोर्ट-आधारित वर्चुअलहोस्ट में देखा है)

ध्यान दें कि HTTP_HOST शामिल नहीं है :443 HTTPS पर चलते समय (जब तक कि आप एक गैर मानक पोर्ट पर चल रहे हों, जिसे मैंने परीक्षण नहीं किया है)।

जैसा कि अन्य ने ध्यान दिया है, आईपीवी 6 का उपयोग करते समय दोनों अलग-अलग होते हैं:

$_SERVER['HTTP_HOST'] == '[::1]'
$_SERVER['SERVER_NAME'] == '::1'

निर्भर करता है कि मैं क्या खोजना चाहता हूं। SERVER_NAME सर्वर का होस्ट नाम है, जबकि HTTP_HOST वर्चुअल होस्ट है जो क्लाइंट से जुड़ा हुआ है।


मुझे समझने में थोड़ी देर लग गई कि ' SERVER_NAME ' का अर्थ क्या है और अधिक विश्वसनीय है। मैं एक साझा सर्वर का उपयोग करता हूं और वर्चुअल होस्ट निर्देशों तक पहुंच नहीं है। इसलिए, मैं अलग-अलग निर्देशिकाओं में विभिन्न HTTP_HOST एस को मैप करने के लिए .htaccess में mod_rewrite का उपयोग करता हूं। उस स्थिति में, यह HTTP_HOST है जो सार्थक है।

स्थिति समान है यदि कोई नाम-आधारित वर्चुअल होस्ट का उपयोग करता है: वर्चुअल होस्ट के भीतर ServerName निर्देश केवल यह कहता है कि इस वर्चुअल होस्ट को कौन सा होस्टनाम मैप किया जाएगा। निचली पंक्ति यह है कि, दोनों मामलों में, क्लाइंट द्वारा अनुरोध ( HTTP_HOST ) के दौरान प्रदान किया गया होस्टनाम, सर्वर के नाम से मेल खाना चाहिए, जो स्वयं निर्देशिका में मैप किया गया है। चाहे मैपिंग वर्चुअल होस्ट निर्देशों के साथ किया गया हो या htaccess mod_rewrite नियमों के साथ यहां माध्यमिक है। इन मामलों में, HTTP_HOST SERVER_NAME के समान होगा। मुझे खुशी है कि अपाचे इस तरह से कॉन्फ़िगर किया गया है।

हालांकि, आईपी-आधारित वर्चुअल होस्ट के साथ स्थिति अलग है। इस मामले में और केवल इस मामले में, SERVER_NAME और HTTP_HOST भिन्न हो सकते हैं, क्योंकि अब क्लाइंट आईपी द्वारा सर्वर का चयन करता है, नाम से नहीं। दरअसल, विशेष विन्यास हो सकते हैं जहां यह महत्वपूर्ण है।

इसलिए, अब से शुरू होने पर, मैं SERVER_NAME का उपयोग SERVER_NAME , बस अगर मेरा कोड इन विशेष कॉन्फ़िगरेशन में पोर्ट किया गया हो।


HTTP_HOST HTTP अनुरोध शीर्षलेख से प्राप्त किया जाता है और यह क्लाइंट वास्तव में अनुरोध के "लक्ष्य होस्ट" के रूप में उपयोग किया जाता है। SERVER_NAME को सर्वर कॉन्फ़िगरेशन में परिभाषित किया गया है। इसका उपयोग करने के लिए आपको किस चीज की आवश्यकता है उस पर निर्भर करता है। आपको अब यह महसूस करना चाहिए कि एक ग्राहक-नियंत्रित मूल्य है जो व्यापार तर्क में उपयोग के लिए विश्वसनीय नहीं हो सकता है और दूसरा सर्वर-नियंत्रित मूल्य है जो अधिक विश्वसनीय है। हालांकि आपको यह सुनिश्चित करने की आवश्यकता है कि प्रश्न में वेबसर्वर में SERVER_NAME सही तरीके से कॉन्फ़िगर किया गया है। एक उदाहरण के रूप में अपाचे HTTPD लेना, यहां अपने दस्तावेज़ से निकास है :

यदि कोई ServerName निर्दिष्ट नहीं है, तो सर्वर आईपी पते पर रिवर्स लुकअप करके होस्टनाम को कम करने का प्रयास करता है। यदि ServerName में कोई पोर्ट निर्दिष्ट नहीं है, तो सर्वर आने वाले अनुरोध से पोर्ट का उपयोग करेगा। इष्टतम विश्वसनीयता और भविष्यवाणी के लिए, आपको ServerName निर्देश का उपयोग कर एक स्पष्ट होस्टनाम और पोर्ट निर्दिष्ट करना चाहिए।

अपडेट करें : अपने प्रश्न पर पेक्का के जवाब की जांच करने के बाद जिसमें बॉबन्स के जवाब का एक लिंक शामिल है कि PHP हमेशा SERVER_NAME लिए HTTP_HOST का मान वापस कर SERVER_NAME , जो कि मेरे अपने PHP 4.x + अपाचे HTTPD 1.2.x अनुभवों के विरुद्ध चला जाता है साल पहले, मैंने अपने मौजूदा एक्सएएमपीपी पर्यावरण से विंडोज एक्सपी (अपाचे HTTPD 2.2.1 PHP 5.2.8 के साथ) पर कुछ धूल उड़ा दी, इसे शुरू किया, एक PHP पृष्ठ बनाया जो दोनों मानों को प्रिंट करता है, संशोधित करने के लिए URLConnection का उपयोग करके जावा परीक्षण अनुप्रयोग बनाया Host हेडर और परीक्षणों ने मुझे सिखाया कि यह वास्तव में (गलत तरीके से) मामला है।

पहले विषय के बारे में कुछ PHP बग रिपोर्ट में PHP और खुदाई करने के बाद, मैंने सीखा कि समस्या का मूल वेब सर्वर में उपयोग किया गया है, जब SERVER_NAME से अनुरोध किया गया था तो यह गलत तरीके से HTTP Host शीर्षलेख लौटा दिया। इसलिए मैंने इस विषय के बारे में विभिन्न कीवर्ड का उपयोग करके अपाचे HTTPD बग रिपोर्ट में खोला और अंत में मुझे एक संबंधित बग मिला। यह व्यवहार अपाचे HTTPD 1.3 के आसपास से पेश किया गया था। आपको UseCanonicalName में ServerName की <VirtualHost> प्रविष्टि में उपयोग करने के लिए UseCanonicalName निर्देश सेट करने की आवश्यकता है ( UseCanonicalName के निचले हिस्से में चेतावनी भी देखें!)।

<VirtualHost *>
    ServerName example.com
    UseCanonicalName on
</VirtualHost> 

यह मेरे लिए काम किया।

संक्षेप में, SERVER_NAME अधिक विश्वसनीय है, लेकिन आप सर्वर कॉन्फ़िगरेशन पर निर्भर हैं!





server-variables