কীভাবে পিএইচএসপি-র বডি পাবেন?


273

আমি নিম্নলিখিত পিএইচপি পৃষ্ঠায় পোষ্ট হিসাবে জমা দিই:

{a:1}

এটি অনুরোধের মূল অংশ (একটি পোষ্ট অনুরোধ)।
পিএইচপি-তে, এই মানটি বের করতে আমাকে কী করতে হবে?

var_dump($_POST); 

সমাধান নয়, কাজ করছে না।


23
এটি RESTful API গুলি তৈরির সন্ধানকারী ব্যক্তিদের জন্য একটি সহায়ক প্রশ্ন। বেশিরভাগই তাদের স্ক্রিপ্টগুলিতে জমা দেওয়া কাঁচা ইনপুট ডেটা কীভাবে অ্যাক্সেস করবেন তা জানেন না কারণ এটি $_POSTসুপারগ্লোবালের মাধ্যমে পাওয়া যায় না । এটি পিটিপি অনুরোধের ক্ষেত্রেও (বিশেষত) সত্য, কারণ পিএইচপি-র কোনও সুসংগঠিত নেই।
rdlowrey


1
এটি লক্ষণীয় যে $ _POST নামটি বিভ্রান্তিমূলক, কারণ কোনও পোষ্ট অনুরোধের কোনও ধরণের ডেটা সেখানে থাকবে না, তবে কেবল যখন বিষয়বস্তুর প্রকারটি অ্যাপ্লিকেশন / x-www-form-
urlencoded

উত্তর:


549

কোনও পোস্ট বা পুট অনুরোধের (বা অন্য কোনও HTTP পদ্ধতি) এর সত্তা বডিটি অ্যাক্সেস করতে:

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

এছাড়াও, STDINধ্রুবক এটিতে ইতিমধ্যে খোলার স্ট্রিম php://input, যাতে আপনি বিকল্পভাবে এটি করতে পারেন:

$entityBody = stream_get_contents(STDIN);

থেকে আমি পিএইচপি ম্যানুয়াল এন্ট্রি ইনপুট / আউটপুট স্ট্রীম করে ডক্স :

পিএইচপি: // ইনপুট একটি পঠনযোগ্য স্ট্রিম যা আপনাকে অনুরোধের বডি থেকে কাঁচা ডেটা পড়তে দেয়। পোষ্ট অনুরোধগুলির ক্ষেত্রে, এটি পিএইচপি: // ইনপুট ব্যবহার করা আরও ভাল $HTTP_RAW_POST_DATAকারণ এটি বিশেষ পিএইচপি.এনআই নির্দেশের উপর নির্ভর করে না। তদুপরি, সেই ক্ষেত্রে যেখানে $HTTP_RAW_POST_DATAডিফল্টরূপে জনবহুল হয় না, এটি সর্বদা_ জনপরিচয়_র_পোস্ট_ডেটা সক্রিয় করার একটি সম্ভাব্য কম মেমরি নিবিড় বিকল্প। পিএইচপি: // ইনপুট এনক্রিপ = "মাল্টিপার্ট / ফর্ম-ডেটা" সহ উপলভ্য নয়।

বিশেষত আপনি লক্ষ করতে চান যে php://inputস্ট্রিমটি, আপনি এটি কোনও ওয়েব এসপিআইতে কীভাবে অ্যাক্সেস করেন তা নির্বিশেষে, সন্ধানযোগ্য নয় । এর অর্থ এটি কেবল একবার পড়া যায়। আপনি যদি এমন পরিবেশে কাজ করছেন যেখানে বৃহত এইচটিটিপি সত্তা সংস্থা নিয়মিত আপলোড হয় আপনি তার স্ট্রিম ফর্মটিতে ইনপুটটি বজায় রাখতে চান (উপরের প্রথম উদাহরণের মতো এটি বাফারিং না করে)।

স্ট্রিম রিসোর্স বজায় রাখতে এরকম কিছু সহায়ক হতে পারে:

<?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অস্থায়ী ফাইলটি ব্যবহারের আগে বাইটে মেমরি রাখতে সর্বোচ্চ সর্বাধিক পরিমাণ ডাটা থাকে।

অবশ্যই, যদি না আপনি ইনপুট স্ট্রিমটি সন্ধানের জন্য সত্যিকারের ভাল কারণ না পান তবে কোনও ওয়েব অ্যাপ্লিকেশনটিতে আপনার এই কার্যকারিতাটির প্রয়োজন হবে না। এইচটিটিপি অনুরোধ সত্তা বডি একবার পড়ার জন্য সাধারণত যথেষ্ট - আপনার অ্যাপ্লিকেশনটি কী করবে তা নির্ধারণের সময় ক্লায়েন্টদের সারাদিন অপেক্ষা করবেন না।

মনে রাখবেন যে Content-Type: multipart/form-dataশিরোনাম নির্দিষ্ট করার জন্য ( enctype="multipart/form-data"এইচটিএমএল আকারে) অনুরোধগুলির জন্য পিএইচপি: // ইনপুট উপলব্ধ নয় । পিএইচপি থেকে প্রাপ্ত ফলাফলগুলি ইতিমধ্যে ফর্মের ডেটা $_POSTসুপারগ্লোবলে পার্স করেছে ।


17
দয়া করে মনে রাখবেন যে আফগানরা, সিজিআই ব্যবহার করে পিএইচপি চলমান সিস্টেমে এসটিডিআইএন স্ট্রিম উপলব্ধ নয়, যেমন মোড_ফসিজিড বা মোড_ফেস্কি ইত্যাদির মাধ্যমে
সিসি

তবে, আমি অনুরোধের সাথে ভেরিয়েবল (ফর্ম-ডেটা হিসাবে) পাস করছি, আমি কীভাবে নির্দিষ্ট মানটি অ্যাক্সেস করতে পারি, আমি অনুরোধটির সাথে গ্র্যান্ট-টাইপ = পাসওয়ার্ড এবং ব্যবহারকারীর নাম = ব্যবহারকারী এবং পাসওয়ার্ড = ফর্ম-ডেটা বডি হিসাবে পাস করছি, কীভাবে আমি "" ইনিটিবিডি "
আনোয়ার পিকে

আমার পরীক্ষা অনুসারে, এটি কন্টেন্ট-টাইপের জন্যও php://inputফাঁকা application/x-www-form-urlencoded(পাশাপাশি multipart/form-data)
ইয়াকোভএল

6
@ এসসি এর প্রতিক্রিয়ায় প্রসারিত করতে: এসটিডিএন উপলব্ধ নয়, তবে 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 এপিআই প্ল্যাটফর্ম তৈরির প্রসঙ্গে এই প্রশ্নটি জিজ্ঞাসা করা হয়েছিল।
Itay Moav -Malimovka

আপনি কি বোঝাতে চাচ্ছেন তা আমি নিশ্চিত নই? একটি রেস্ট এপিআই ঠিক সেই পথটিতে পুনঃনির্দেশগুলি খুঁজে পেতে পারে, এটি আমার ছিল সমস্যা।
লেগোলাস

আমি যখন জিজ্ঞাসা করেছি তখন আমি বোঝাতে চেয়েছি, আমি কোনও বাগ সমাধানের চেষ্টা করছিলাম না, বরং এটি কীভাবে বিকাশ করা যায় তা বোঝার চেষ্টা করছি।
Itay Moav -Malimovka

3
এই ইঙ্গিতটি আমার দিনকে বাঁচিয়েছিল। প্রাপ্তি সার্ভারটি কিছু এপিআই ক্লায়েন্টকে ভেঙে https এ পুনর্নির্দেশ করতে পুনরায় কনফিগার করা হয়েছে।
মরুভূমি

আসলে আমার অনুরোধ ছিল POSTকিন্তু তদন্তের পরে এটি দেখাচ্ছে যে এটি ছিল GET। আমি একবার /আমার ইউআরএল এর শেষে একটি যুক্ত করেছি, এটি পোস্ট করা শুরু করে। অদ্ভুত!
জ্যাকিগৌরভ

4

ভেরিয়েবল পরীক্ষা করুন$HTTP_RAW_POST_DATA


7
কাঁচা পোষ্ট ডেটা অ্যাক্সেসের জন্য পছন্দসই পদ্ধতি হ'ল php://input$HTTP_RAW_POST_DATAসঙ্গে পাওয়া যায় না enctype="multipart/form-data"
নৈর্ব্যতা

38
এই বৈশিষ্ট্যটি পিএইচপি 5.6.0 এ মঞ্জুর করা হয়েছিল এবং পিএইচপি 7.0.0 অনুযায়ী সরানো হয়েছিল।
চার্লস

3

যদি আপনি এইচটিটিপি পিইসিএল এক্সটেনশানটি ইনস্টল করেন তবে আপনি http_get_request_body()স্ট্রিং হিসাবে বডি ডেটা পেতে ফাংশনটি ব্যবহার করতে পারেন ।


ফাংশন বিদ্যমান নেই।
রিক


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খালি অ্যারেটি ফিরিয়ে দেওয়া উচিত। কেউ যদি এক্সএমএল বা ওয়াইএএমএল জমা দেয় তবে কী হবে? সামগ্রী-প্রকারের জন্য একটি পরীক্ষা যুক্ত করুন এবং সেখান থেকে যান।
অ্যান্টনি রুটলেজ

এছাড়াও, এইচটিটিপি অনুরোধ পদ্ধতিটি যদি আপনি ইনপুট ডেটা গ্রহণ করতে চান তবে তা নির্ধারণ করতে পারে। $_SERVERদরকারী মান পরীক্ষা করার জন্য সুপারগ্লোবাল দেখুন ।
অ্যান্টনি রুটলেজ

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.