Php में POST का बॉडी कैसे प्राप्त करें?


273

मैं निम्नलिखित के रूप में एक php पृष्ठ पर पोस्ट के रूप में प्रस्तुत करता हूं:

{a:1}

यह अनुरोध (एक POST अनुरोध) का निकाय है।
Php में, मुझे उस मूल्य को निकालने के लिए क्या करना होगा?

var_dump($_POST); 

समाधान नहीं है, काम नहीं कर रहा है।


23
यह Restful API बनाने के इच्छुक लोगों के लिए एक उपयोगी प्रश्न है। अधिकांश यह नहीं जानते कि कच्चे लिपियों के डेटा को उनकी स्क्रिप्ट में कैसे पहुँचा जाए क्योंकि यह $_POSTसुपरग्लोब के माध्यम से उपलब्ध नहीं है । यह PUT अनुरोधों के मामले में भी (विशेष रूप से) सही है, क्योंकि PHP के पास कोई सुपरग्लोबल नहीं है।
rdlowrey


1
यह ध्यान देने योग्य है कि नाम $ _POST भ्रामक है, क्योंकि POST अनुरोध से किसी भी प्रकार का डेटा नहीं होगा, लेकिन केवल तब जब सामग्री का प्रकार आवेदन / x-www-form-urlencoded या मल्टीपार्ट / फॉर्म-डेटा हो
पेट्रूजा

जवाबों:


549

POST या PUT अनुरोध (या किसी अन्य HTTP विधि) के निकाय तक पहुँचने के लिए:

$entityBody = file_get_contents('php://input');

इसके अलावा, STDINस्थिरांक एक पहले से खुली हुई धारा है php://input, जिससे आप वैकल्पिक रूप से कर सकते हैं:

$entityBody = stream_get_contents(STDIN);

से मैं पर पीएचपी मैनुअल प्रविष्टि / ओ धाराओं डॉक्स :

php: // input एक केवल पढ़ने वाली स्ट्रीम है जो आपको अनुरोध बॉडी के कच्चे डेटा को पढ़ने की अनुमति देता है। पोस्ट अनुरोध के मामले में, यह उपयोग करने के लिए बेहतर है php: // इनपुट के बजाय $HTTP_RAW_POST_DATAके रूप में यह विशेष php.ini निर्देशों पर निर्भर नहीं करता। इसके अलावा, उन मामलों के लिए, जहां $HTTP_RAW_POST_DATAडिफ़ॉल्ट रूप से आबादी नहीं है, यह हमेशा चालू रखने के लिए एक संभावित कम मेमोरी गहन विकल्प है। php: // input enctype = "मल्टीपार्ट / फॉर्म-डेटा" के साथ उपलब्ध नहीं है।

विशेष रूप से आप यह नोट करना चाहेंगे कि php://inputस्ट्रीम, चाहे आप इसे किसी वेब SAPI में कैसे एक्सेस करें, यह खोजी नहीं है । इसका मतलब है कि यह केवल एक बार पढ़ा जा सकता है। यदि आप एक ऐसे वातावरण में काम कर रहे हैं जहाँ बड़े HTTP निकाय निकायों को नियमित रूप से अपलोड किया जाता है, तो आप इनपुट को उसके स्ट्रीम रूप में बनाए रखना चाह सकते हैं (बजाय इसके पहले उदाहरण की तरह बफ़र करना)।

धारा संसाधन को बनाए रखने के लिए कुछ इस तरह मददगार हो सकता है:

<?php

function detectRequestBody() {
    $rawInput = fopen('php://input', 'r');
    $tempStream = fopen('php://temp', 'r+');
    stream_copy_to_stream($rawInput, $tempStream);
    rewind($tempStream);

    return $tempStream;
}

php://tempआपको मेमोरी खपत का प्रबंधन करने की अनुमति देता है क्योंकि यह डेटा की एक निश्चित राशि संग्रहीत होने के बाद पारदर्शी रूप से फाइलसिस्टम स्टोरेज में बदल जाएगा (डिफ़ॉल्ट रूप से 2 एम)। इस आकार को php.ini फ़ाइल में जोड़कर या जोड़कर /maxmemory:NN, NNअस्थायी फ़ाइल का उपयोग करने से पहले मेमोरी में रखने के लिए डेटा की अधिकतम मात्रा बाइट्स में बताई जा सकती है।

बेशक, जब तक आपके पास इनपुट स्ट्रीम पर मांग करने का एक बहुत अच्छा कारण नहीं है, तब तक आपको वेब एप्लिकेशन में इस कार्यक्षमता की आवश्यकता नहीं होनी चाहिए। HTTP अनुरोध इकाई निकाय को पढ़ना एक बार आम तौर पर पर्याप्त होता है - ग्राहकों को पूरे दिन इंतजार नहीं करना चाहिए जबकि आपका ऐप यह बताता है कि क्या करना है।

ध्यान दें कि php: // इनपुट Content-Type: multipart/form-dataहेडर निर्दिष्ट करने के अनुरोध के लिए उपलब्ध नहीं है ( enctype="multipart/form-data"HTML रूपों में)। PHP से यह परिणाम पहले से ही फॉर्म डेटा को $_POSTसुपरग्लोबल में पार्स कर दिया है ।


17
कृपया ध्यान दें कि एफएआईसीएस, एसटीडीआई स्ट्रीम सीजीआई का उपयोग करके सिस्टम चलाने पर उपलब्ध नहीं है, अर्थात mod_fcgid या mod_fastcgi आदि के माध्यम से
scy

लेकिन, मैं अनुरोध के साथ चर (प्रपत्र-डेटा के रूप में) पास कर रहा हूं, मैं निर्दिष्ट मान तक कैसे पहुंच सकता हूं, मैं अनुदान_ पासवर्ड या उपयोगकर्ता नाम और उपयोगकर्ता = पासवर्ड दे रहा हूं = अनुरोध के साथ प्रपत्र-डेटा निकाय के रूप में पास करता हूं, मुझे "$" के लिए अनुदान_प्रकार कैसे मिलेगा UnitBody "
अनवर पीके

मेरे परीक्षण के अनुसार, यह सामग्री-प्रकार के साथ-साथ (इसके अलावा ) के php://inputलिए खाली हैapplication/x-www-form-urlencodedmultipart/form-data
याकोवैल

6
@ Scy की प्रतिक्रिया पर विस्तार करने के लिए: STDIN उपलब्ध नहीं है, लेकिन php://inputहै। इसलिए (फास्ट) सीजीआई कॉन्फ़िगरेशन stream_get_contents(STDIN)काम नहीं file_get_contents("php://input")करेगा।
साइनस मैकॉवेती

16

ऐरे में वापसी मूल्य

 $data = json_decode(file_get_contents('php://input'), true);

इस परिदृश्य में, अब आपको $dataजाँचने के लिए साहचर्य सरणी के माध्यम से लूप करना होगा कि क्या प्रत्येक मान आपकी इच्छानुसार एन्कोडेड है। चीजों को देखने का "स्ट्रीम-टू-डेटाटाइप" तरीका सरल हो सकता है, लेकिन यह स्ट्रीम फ़िल्टर का उपयोग करके "स्ट्रीम फॉर्म" में एन्कोडिंग से निपटने के लिए उतना कुशल नहीं हो सकता है। यदि आप एन्कोडिंग मुद्दों को संभाल नहीं रहे हैं और केवल स्वच्छता और सत्यापन कर रहे हैं, तो आप एक कदम याद कर रहे हैं।
एंथनी

13

खाली होने का एक संभावित कारण $_POSTयह है कि अनुरोध नहीं है POST, या POSTअब नहीं है ... यह पोस्ट के रूप में शुरू हो सकता है, लेकिन कहीं एक 301या 302अनुप्रेषित का सामना करना पड़ता है, जिसे स्विच किया जाता है GET!

$_SERVER['REQUEST_METHOD']यदि यह मामला है, तो जांच करने के लिए निरीक्षण करें।

यह क्यों नहीं होना चाहिए, लेकिन अभी भी करता है की एक अच्छी चर्चा के लिए https://stackoverflow.com/a/19422232/109787 देखें ।


1
यह सवाल REST एपि प्लेटफॉर्म विकसित करने के संदर्भ में पूछा गया था।
इते मूव -मालिमोवका

मुझे नहीं पता तुम्हारा क्या मतलब है? REST एपि केवल पथ में पुनर्निर्देशित हो सकता है, यही वह मुद्दा है जो मेरे पास था।
लेगोलस

मेरा मतलब था जब मैंने सवाल पूछा, मैं बग को हल करने की कोशिश नहीं कर रहा था, बल्कि यह पता लगाने की कोशिश कर रहा था कि इसे कैसे विकसित किया जाए।
इतय मोव -मालिमोवका १ay

3
इस संकेत ने मेरा दिन बचाया। प्राप्तकर्ता को कुछ एपीआई क्लाइंट को तोड़ने वाले https पर पुनर्निर्देशित करने के लिए प्राप्त सर्वर को फिर से कॉन्फ़िगर किया गया है।
डेजर्टएगल

वास्तव में मेरा अनुरोध था, POSTलेकिन निरीक्षण करने के बाद यह दिखा रहा था कि यह था GET। एक बार जब मैंने /अपने URL के अंत में जोड़ा , तो उसने POST दिखाना शुरू कर दिया। अजीब!
zackygaurav 15

4

चर की जाँच करें$HTTP_RAW_POST_DATA


7
कच्चे POST डेटा तक पहुँचने की पसंदीदा विधि है php://input$HTTP_RAW_POST_DATAके साथ उपलब्ध नहीं है enctype="multipart/form-data"
अशक्तता

38
इस सुविधा को PHP 5.6.0 में हटा दिया गया था, और PHP 7.0.0 के रूप में बनाया गया था।
चार्ल्स

3

यदि आपने HTTP PECL एक्सटेंशन स्थापित किया है, तो आप http_get_request_body()स्ट्रिंग के रूप में बॉडी डेटा प्राप्त करने के लिए फ़ंक्शन का उपयोग कर सकते हैं ।


फ़ंक्शन मौजूद नहीं है।
रिक

2

यदि आपके पास pecl / http एक्सटेंशन स्थापित है, तो आप इसका उपयोग भी कर सकते हैं:

$request = new http\Env\Request();
$request->getBody();

2
function getPost()
{
    if(!empty($_POST))
    {
        // when using application/x-www-form-urlencoded or multipart/form-data as the HTTP Content-Type in the request
        // NOTE: if this is the case and $_POST is empty, check the variables_order in php.ini! - it must contain the letter P
        return $_POST;
    }

    // when using application/json as the HTTP Content-Type in the request 
    $post = json_decode(file_get_contents('php://input'), true);
    if(json_last_error() == JSON_ERROR_NONE)
    {
        return $post;
    }

    return [];
}

print_r(getPost());

यह जो थोड़ा सा तर्क याद आ रहा है वह सामग्री-प्रकार हेडर में पाए गए मूल्य का परीक्षण है। इसका अनुसरण केवल इसलिए नहीं किया जाता है क्योंकि $ _POST खाली है जिसे JSON सबमिट किया जाना चाहिए, या यदि json_last_error() == JSON_ERROR_NONEऐसा है false, कि एक खाली सरणी वापस आनी चाहिए। अगर किसी ने XML या YAML जमा किया है तो क्या होगा? सामग्री-प्रकार के लिए एक परीक्षण जोड़ें और वहां से जाएं।
एंथनी

इसके अलावा, यदि आप इनपुट डेटा को स्वीकार करना चाहते हैं तो HTTP अनुरोध विधि निर्धारित कर सकती है। $_SERVERजाँच करने के लिए उपयोगी मूल्यों के लिए सुपरग्लोबल देखें ।
एंथनी

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.