Я надсилаю як 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 не має відповідних надглобальних.