Я надсилаю як POST на сторінку php наступне:
{a:1}
Це тіло запиту (POST-запит).
У PHP, що мені потрібно зробити, щоб отримати це значення?
var_dump($_POST);
не рішення, не працює.
Я надсилаю як POST на сторінку php наступне:
{a:1}
Це тіло запиту (POST-запит).
У PHP, що мені потрібно зробити, щоб отримати це значення?
var_dump($_POST);
не рішення, не працює.
Відповіді:
Щоб отримати доступ до тіла особи запиту POST або PUT (або будь-якого іншого методу HTTP):
$entityBody = file_get_contents('php://input');
Крім того, STDINконстанта - це вже відкритий потік для php://input, тому ви можете:
$entityBody = stream_get_contents(STDIN);
З документа PHP в документах потоків вводу / виводу :
php: // вхід - це потік лише для читання, який дозволяє читати необроблені дані з тіла запиту. У випадку запитів POST бажано використовувати php: // input, а не
$HTTP_RAW_POST_DATAоскільки це не залежить від спеціальних директив php.ini. Більше того, для тих випадків, коли$HTTP_RAW_POST_DATAне заповнено за замовчуванням, це потенційно менш об'ємна пам'ять, альтернатива активації завжди_populate_raw_post_data. php: // введення недоступне з 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надглобальний.
php://inputтакож порожнє для application/x-www-form-urlencodedконтент-типу (крім того multipart/form-data)
php://inputє. Тож поки на (швидких) CGI конфігураціях stream_get_contents(STDIN)не працюватиме, file_get_contents("php://input")буде.
повернути значення в масиві
$data = json_decode(file_get_contents('php://input'), true);
$dataасоціативний масив, щоб перевірити, чи кожне значення закодовано так, як ви хочете. Спосіб погляду на речі "потік до даних" може бути спрощеним, але він може бути не таким ефективним, як справу з кодуванням у "потоковій формі" за допомогою фільтра потоку. Якщо ви не вирішуєте проблеми з кодуванням і просто дезінфікуєте та перевіряєте, вам пропущено крок.
Можливою причиною порожній $_POSTє те , що клопотання не POST, або НЕ POSTбільше ... Це , можливо, почали, як пост, але виявив 301або 302перенаправляти куди - небудь, який переключається на GET!
Перевірте, $_SERVER['REQUEST_METHOD']чи це так.
Дивіться https://stackoverflow.com/a/19422232/109787, щоб добре обговорити, чому цього не має відбуватися, але все-таки все-таки є.
POSTале після огляду він показав, що це було GET. Після того, як я додав a /в кінці своєї URL-адреси, він почав показувати POST. Дивно!
Перевірте $HTTP_RAW_POST_DATAзмінну
php://input. $HTTP_RAW_POST_DATAнедоступний для enctype="multipart/form-data".
Якщо ви встановили розширення HTTP PECL, ви можете скористатися http_get_request_body()функцією отримання даних про тіло у вигляді рядка.
Якщо у вас встановлено розширення pecl / http , ви також можете скористатися цим:
$request = new http\Env\Request();
$request->getBody();
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());
json_last_error() == JSON_ERROR_NONEце так false, слід повернути порожній масив. Що робити, якщо хтось подав XML або YAML? Додайте тест на Content-Type і перейдіть звідти.
$_SERVERкорисні значення для суперглобалу.
http_get_request_body()явно зроблено для отримання тіла PUTта POSTзапитів відповідно до документації http://php.net/manual/fa/function.http-get-request-body.php
$_POSTсуперглобал. Це також (особливо) вірно у випадку запитів PUT, оскільки PHP не має відповідних надглобальних.