मुझे JQuery से अजाक्स अनुरोधों के साथ बातचीत करने के php://input
बजाय विधि का उपयोग करने के लिए निर्देशित किया गया है $_POST
। जो मुझे समझ में नहीं आता है वह यह है कि वैश्विक बनाम इस का उपयोग करने के फायदे हैं $_POST
या $_GET
।
मुझे JQuery से अजाक्स अनुरोधों के साथ बातचीत करने के php://input
बजाय विधि का उपयोग करने के लिए निर्देशित किया गया है $_POST
। जो मुझे समझ में नहीं आता है वह यह है कि वैश्विक बनाम इस का उपयोग करने के फायदे हैं $_POST
या $_GET
।
जवाबों:
कारण यह है कि php://input
HTTP-हेडर के बाद सभी कच्चे डेटा को रिटर्न करता है, भले ही सामग्री प्रकार की परवाह किए बिना।
PHP सुपरग्लोबल $_POST
, केवल उस डेटा को रैप करने वाला है जो या तो है
application/x-www-form-urlencoded
(साधारण फॉर्म-पोस्ट के लिए मानक सामग्री प्रकार) याmultipart/form-data
(ज्यादातर फ़ाइल अपलोड के लिए उपयोग किया जाता है)ऐसा इसलिए है क्योंकि ये केवल सामग्री प्रकार हैं जो उपयोगकर्ता एजेंटों द्वारा समर्थित होने चाहिए । इसलिए सर्वर और PHP परंपरागत रूप से किसी अन्य सामग्री प्रकार (जिसका अर्थ यह नहीं है कि वे नहीं कर सकते थे) प्राप्त करने की उम्मीद नहीं करते हैं।
इसलिए, यदि आप एक अच्छे पुराने HTML को बस पोस्ट करते हैं form
, तो अनुरोध कुछ इस तरह दिखता है:
POST /page.php HTTP/1.1
key1=value1&key2=value2&key3=value3
लेकिन अगर आप अजाक्स के साथ बहुत काम कर रहे हैं, तो इस प्रोबाईबी में प्रकारों (स्ट्रिंग, इंट, बूल) और संरचनाओं (सरणियों, वस्तुओं) के साथ अधिक जटिल डेटा का आदान-प्रदान भी शामिल है, इसलिए ज्यादातर मामलों में JSON सबसे अच्छा विकल्प है। लेकिन JSON-पेलोड के साथ एक अनुरोध कुछ इस तरह दिखाई देगा:
POST /page.php HTTP/1.1
{"key1":"value1","key2":"value2","key3":"value3"}
सामग्री अब application/json
(या कम से कम उपरोक्त में से कोई भी नहीं) होगी, इसलिए PHP का $_POST
-wrapper नहीं जानता कि उसे (अभी तक) कैसे संभालना है।
डेटा अभी भी वहाँ है, आप बस इसे आवरण के माध्यम से उपयोग नहीं कर सकते। इसलिए आपको इसे कच्चे प्रारूप में खुद के साथ लाने की जरूरत है file_get_contents('php://input')
( जब तक कि यह multipart/form-data
-कोड नहीं है )।
यह भी है कि आप एक्सएमएल-डेटा या किसी अन्य गैर-मानक सामग्री प्रकार का उपयोग कैसे करेंगे।
application/json
लिए मान्य डेटा स्रोत के रूप में पहचानने से कुछ भी नहीं रोकता है $_POST
। और विशेष रूप से उस समर्थन के लिए भी प्रकाशित अनुरोध हैं।
php://input
आप डेटा के कच्चे बाइट्स दे सकते हैं। यह तब उपयोगी है जब POSTed डेटा एक JSON एनकोडेड संरचना है, जो अक्सर AJAX POST अनुरोध के लिए होता है।
यहाँ एक ऐसा करने का कार्य है:
/**
* Returns the JSON encoded POST data, if any, as an object.
*
* @return Object|null
*/
private function retrieveJsonPostData()
{
// get the raw POST data
$rawData = file_get_contents("php://input");
// this returns null if not valid json
return json_decode($rawData);
}
$_POST
जब आप एक रूप है, एक पारंपरिक पोस्ट द्वारा प्रस्तुत से मुख्य मान डेटा संभाल रहे सरणी अधिक उपयोगी है। यह केवल तभी काम करता है जब POSTed डेटा किसी मान्यता प्राप्त प्रारूप में होता है, आमतौर पर application/x-www-form-urlencoded
( विवरण के लिए http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4 देखें)।
true
दूसरे पैरामीटर के रूप में पास करते हैं json_decode
, तो यह एक सहयोगी सरणी लौटाएगा।
यदि पोस्ट डेटा विकृत है, तो $ _POST में कुछ भी नहीं होगा। फिर भी, php: // इनपुट में विकृत स्ट्रिंग होगा।
उदाहरण के लिए कुछ अजाक्स अनुप्रयोग हैं, जो किसी फ़ाइल को अपलोड करने के लिए सही पोस्ट की-वैल्यू अनुक्रम नहीं बनाते हैं, और बस सभी डेटा को पोस्ट डेटा के रूप में डंप करते हैं, बिना चर नाम या कुछ भी। $ _POST खाली होगा, $ _FILES खाली भी होगा, और php: // इनपुट में एक स्ट्रिंग के रूप में लिखी गई सटीक फ़ाइल होगी।
PHP स्पष्ट रूप से आपको HTTP अनुरोधों को संभालने के लिए एक शुद्ध REST (GET, POST, PUT, PATCH, DELETE) जैसा इंटरफ़ेस देने के लिए नहीं बनाया गया था ।
हालांकि, $_POST
, $_GET
, और $_FILES
superglobals , और समारोह filter_input_array()
औसत व्यक्ति के / आम आदमी की जरूरतों के लिए बहुत उपयोगी हैं।
$_POST
(और $_GET
) का एक छिपा हुआ लाभ यह है कि आपके इनपुट डेटा को PHP द्वारा स्वचालित रूप से urldecoded किया जाता है । आप कभी भी ऐसा करने के बारे में नहीं सोचते हैं, विशेष रूप से एक मानक GET अनुरोध के भीतर क्वेरी स्ट्रिंग मापदंडों के लिए।
यह कहा जा रहा है, जैसा कि आप अपने प्रोग्रामिंग ज्ञान में आगे बढ़ते हैं और जावास्क्रिप्ट का उपयोग करना चाहते हैं XmlHttpRequest
(कुछ के लिए jQuery), आप इस योजना की सीमा को देखने के लिए आते हैं।
$_POST
HTTP Content-Type
हेडर में दो मीडिया प्रकारों के उपयोग के लिए आपको सीमित करता है :
application/x-www-form-urlencoded
, तथाmultipart/form-data
इस प्रकार, यदि आप सर्वर पर PHP में डेटा मान भेजना चाहते हैं, और यह $_POST
सुपरग्लोबल में दिखाई देता है , तो आपको इसे क्लाइंट-साइड पर urlencode करना होगा और उक्त डेटा को कुंजी / मान युग्म के रूप में भेजना होगा - नौसिखियों के लिए असुविधाजनक कदम। (विशेष रूप से यह पता लगाने की कोशिश करते हुए कि URL के विभिन्न हिस्सों को urlencoding के विभिन्न रूपों की आवश्यकता है: सामान्य, कच्चा, आदि)।
आप सभी jQuery के उपयोगकर्ताओं के लिए, $.ajax()
विधि आपके JSON को सर्वर पर भेजने से पहले URL एन्कोडेड कुंजी / मान जोड़े में परिवर्तित कर रही है। आप सेटिंग करके इस व्यवहार को ओवरराइड कर सकते हैं processData: false
। बस $ .ajax () प्रलेखन पढ़ें , और सामग्री प्रकार हेडर में सही मीडिया प्रकार भेजने के लिए मत भूलना।
आमतौर पर, यदि आप एक सामान्य, सिंक्रोनस (जब पूरा पृष्ठ फिर से करता है) HTTP एक HTML फॉर्म के साथ अनुरोध करता है, तो उपयोगकर्ता-एजेंट (वेब ब्राउज़र) आपके फॉर्म डेटा को आपके लिए urlencode करेगा। यदि आप XmlHttpRequest
ऑब्जेक्ट का उपयोग करके एक एसिंक्रोनस HTTP अनुरोध करना चाहते हैं , तो आपको एक urlencoded स्ट्रिंग को फ़ैशन करना होगा और इसे भेजना होगा, यदि आप चाहते हैं कि डेटा $_POST
सुपरग्लोबल में दिखाई दे ।
जावास्क्रिप्ट सरणी या ऑब्जेक्ट से एक urlencoded स्ट्रिंग में परिवर्तित करना कई डेवलपर्स को परेशान करता है (यहां तक कि फॉर्म डेटा जैसे नए एपीआई के साथ )। वे बहुत अधिक सिर्फ JSON भेजने में सक्षम होंगे, और ऐसा करने के लिए क्लाइंट कोड के लिए अधिक कुशल होगा ।
याद रखें (wink, wink), औसत वेब डेवलपर XmlHttpRequest
ऑब्जेक्ट को सीधे उपयोग करना नहीं सीखता है , वैश्विक फ़ंक्शन, स्ट्रिंग फ़ंक्शन, सरणी फ़ंक्शंस, और आपके और I ;-) जैसे नियमित अभिव्यक्ति। उनके लिए उरलकोडिंग एक बुरा सपना है। ;-)
PHP की सहज XML और JSON हैंडलिंग की कमी कई लोगों को बंद कर देती है। आपको लगता है कि यह अब तक (sigh) PHP का हिस्सा होगा।
XML, JSON और YAML सभी में मीडिया प्रकार हैं जिन्हें HTTP Content-Type
हेडर में रखा जा सकता है ।
देखो कितने मीडिया प्रकार (पूर्व में, MIME प्रकार) IANA द्वारा परिभाषित किए गए हैं।
देखो कि कितने HTTP हेडर हैं।
php://input
स्ट्रीम का उपयोग करने से आप शिशु-बैठे / हाथ पकड़े हुए स्तर को दरकिनार कर सकते हैं जिसे PHP ने दुनिया पर मजबूर कर दिया है। :-) महान शक्ति के साथ महान जिम्मेदारी आती है!
अब, इससे पहले कि आप डेटा मानों के साथ सौदा करें php://input
, आपको कुछ चीजें करनी चाहिए।
आह, हा! हां, आप चाहते हैं कि आपके एप्लिकेशन में डेटा स्ट्रीम को UTF-8 इनकोड किया जाए, लेकिन आप यह कैसे जान सकते हैं कि यह है या नहीं?
php://input
।क्या आप यह जानने के बिना स्ट्रीम डेटा को संभालने का प्रयास करने जा रहे हैं कि पहले कितना है? यह एक भयानक विचार है । आप Content-Length
स्ट्रीम किए गए इनपुट के आकार पर मार्गदर्शन के लिए HTTP हेडर पर विशेष रूप से भरोसा नहीं कर सकते क्योंकि यह स्पूफ हो सकता है।
आपको एक की जरूरत है:
क्या आप धारा के एन्कोडिंग को जाने बिना धारा डेटा को यूटीएफ -8 में बदलने का प्रयास करने जा रहे हैं? कैसे? Iconv स्ट्रीम फ़िल्टर ( iconv स्ट्रीम फ़िल्टर उदाहरण ) ऐसा लगता है कि शुरू और अंत एन्कोडिंग चाहते हैं।
'convert.iconv.ISO-8859-1/UTF-8'
इस प्रकार, यदि आप कर्तव्यनिष्ठ हैं, तो आपको आवश्यकता होगी:
( अपडेट : 'convert.iconv.UTF-8/UTF-8'
UTF-8 के लिए सब कुछ करने के लिए मजबूर करेगा, लेकिन आपको अभी भी वर्णों के लिए ध्यान रखना होगा कि iconv लाइब्रेरी अनुवाद करने का तरीका नहीं बता सकती है। दूसरे शब्दों में, आपको कुछ को परिभाषित करना है कि जब चरित्र का अनुवाद नहीं किया जा सकता है तो क्या कार्रवाई करें। : 1) एक डमी चरित्र डालें, 2) असफल / फेंक और अपवाद)।
आप विशेष रूप से HTTP Content-Encoding
हेडर पर भरोसा नहीं कर सकते हैं , क्योंकि यह निम्नलिखित की तरह संपीड़न जैसा कुछ संकेत दे सकता है। यह वह नहीं है जो आप iconv के संबंध में निर्णय लेना चाहते हैं।
Content-Encoding: gzip
भाग I: HTTP अनुरोध संबंधित
भाग II: स्ट्रीम डेटा संबंधित
भाग III: डेटा प्रकार संबंधित
(याद रखें, डेटा अभी भी एक URL एन्कोडेड स्ट्रिंग हो सकता है जिसे आपको तब पार्स और URL डीकोड करना होगा)।
भाग IV: डेटा मूल्य संबंधित
इनपुट डेटा फ़िल्टर करें।
इनपुट डेटा को मान्य करें।
$_POST
Superglobal, इनपुट पर सीमा के लिए php.ini सेटिंग के साथ ही आम आदमी के लिए आसान कर रहे हैं। हालांकि, स्ट्रीम का उपयोग करते समय चरित्र एन्कोडिंग के साथ काम करना बहुत अधिक सहज और कुशल होता है क्योंकि उचित एन्कोडिंग के लिए इनपुट मूल्यों की जांच करने के लिए सुपरग्लोबल्स (या सरणियों) के माध्यम से लूप की आवश्यकता नहीं होती है।
इसलिए मैंने एक फ़ंक्शन लिखा, जो php: // इनपुट स्ट्रीम से POST डेटा प्राप्त करेगा ।
तो यहाँ चुनौती PUT, DELETE या PATCH अनुरोध विधि पर स्विच हो रही थी, और अभी भी उस अनुरोध के साथ भेजा गया पोस्ट डेटा प्राप्त करें।
मैं इसे शायद इसी तरह की चुनौती वाले किसी व्यक्ति के लिए साझा कर रहा हूं। नीचे दिया गया कार्य वह है जिसके साथ मैं आया था और यह काम करता है। मुझे उम्मीद है यह मदद करेगा!
/**
* @method Post getPostData
* @return array
*
* Convert Content-Disposition to a post data
*/
function getPostData() : array
{
// @var string $input
$input = file_get_contents('php://input');
// continue if $_POST is empty
if (strlen($input) > 0 && count($_POST) == 0 || count($_POST) > 0) :
$postsize = "---".sha1(strlen($input))."---";
preg_match_all('/([-]{2,})([^\s]+)[\n|\s]{0,}/', $input, $match);
// update input
if (count($match) > 0) $input = preg_replace('/([-]{2,})([^\s]+)[\n|\s]{0,}/', '', $input);
// extract the content-disposition
preg_match_all("/(Content-Disposition: form-data; name=)+(.*)/m", $input, $matches);
// let's get the keys
if (count($matches) > 0 && count($matches[0]) > 0)
{
$keys = $matches[2];
foreach ($keys as $index => $key) :
$key = trim($key);
$key = preg_replace('/^["]/','',$key);
$key = preg_replace('/["]$/','',$key);
$key = preg_replace('/[\s]/','',$key);
$keys[$index] = $key;
endforeach;
$input = preg_replace("/(Content-Disposition: form-data; name=)+(.*)/m", $postsize, $input);
$input = preg_replace("/(Content-Length: )+([^\n]+)/im", '', $input);
// now let's get key value
$inputArr = explode($postsize, $input);
// @var array $values
$values = [];
foreach ($inputArr as $index => $val) :
$val = preg_replace('/[\n]/','',$val);
if (preg_match('/[\S]/', $val)) $values[$index] = trim($val);
endforeach;
// now combine the key to the values
$post = [];
// @var array $value
$value = [];
// update value
foreach ($values as $i => $val) $value[] = $val;
// push to post
foreach ($keys as $x => $key) $post[$key] = isset($value[$x]) ? $value[$x] : '';
if (is_array($post)) :
$newPost = [];
foreach ($post as $key => $val) :
if (preg_match('/[\[]/', $key)) :
$k = substr($key, 0, strpos($key, '['));
$child = substr($key, strpos($key, '['));
$child = preg_replace('/[\[|\]]/','', $child);
$newPost[$k][$child] = $val;
else:
$newPost[$key] = $val;
endif;
endforeach;
$_POST = count($newPost) > 0 ? $newPost : $post;
endif;
}
endif;
// return post array
return $_POST;
}
इसका उपयोग कैसे करें, इसका सरल उदाहरण
<?php
if(!isset($_POST) || empty($_POST)) {
?>
<form name="form1" method="post" action="">
<input type="text" name="textfield"><br />
<input type="submit" name="Submit" value="submit">
</form>
<?php
} else {
$example = file_get_contents("php://input");
echo $example; }
?>