Tôi gửi POST dưới dạng trang php như sau:
{a:1}
Đây là phần thân của yêu cầu (một yêu cầu POST).
Trong php, tôi phải làm gì để trích xuất giá trị đó?
var_dump($_POST);
không phải là giải pháp, không hoạt động.
Tôi gửi POST dưới dạng trang php như sau:
{a:1}
Đây là phần thân của yêu cầu (một yêu cầu POST).
Trong php, tôi phải làm gì để trích xuất giá trị đó?
var_dump($_POST);
không phải là giải pháp, không hoạt động.
Câu trả lời:
Để truy cập phần thân thực thể của yêu cầu POST hoặc PUT (hoặc bất kỳ phương thức HTTP nào khác):
$entityBody = file_get_contents('php://input');
Ngoài ra, STDIN
hằng số là một luồng đã mở php://input
, vì vậy bạn có thể thay thế:
$entityBody = stream_get_contents(STDIN);
Từ mục nhập thủ công PHP trên tài liệu luồng I / O :
php: // input là luồng chỉ đọc cho phép bạn đọc dữ liệu thô từ thân yêu cầu. Trong trường hợp yêu cầu POST, tốt hơn là sử dụng đầu vào php: // thay vì
$HTTP_RAW_POST_DATA
không phụ thuộc vào các lệnh php.ini đặc biệt. Hơn nữa, đối với những trường hợp$HTTP_RAW_POST_DATA
không được điền theo mặc định, đây là một giải pháp thay thế ít bộ nhớ hơn để kích hoạt always_population_raw_post_data. php: // đầu vào không khả dụng với enctype = "Multipart / form-data".
Cụ thể, bạn sẽ muốn lưu ý rằng php://input
luồng, bất kể bạn truy cập nó như thế nào trong web SAPI, đều không thể tìm kiếm được . Điều này có nghĩa là nó chỉ có thể được đọc một lần. Nếu bạn đang làm việc trong một môi trường nơi các thực thể HTTP lớn được tải lên thường xuyên, bạn có thể muốn duy trì đầu vào ở dạng luồng của nó (thay vì đệm nó như ví dụ đầu tiên ở trên).
Để duy trì tài nguyên luồng, một cái gì đó như thế này có thể hữu ích:
<?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
cho phép bạn quản lý mức tiêu thụ bộ nhớ vì nó sẽ chuyển sang lưu trữ hệ thống tập tin một cách trong suốt sau khi một lượng dữ liệu nhất định được lưu trữ (2M theo mặc định). Kích thước này có thể được thao tác trong tệp php.ini hoặc bằng cách nối thêm /maxmemory:NN
, trong đó NN
lượng dữ liệu tối đa cần giữ trong bộ nhớ trước khi sử dụng tệp tạm thời, tính bằng byte.
Tất nhiên, trừ khi bạn có một lý do thực sự tốt để tìm kiếm trên luồng đầu vào, bạn không nên cần chức năng này trong một ứng dụng web. Đọc phần thân thực thể yêu cầu HTTP một lần thường là đủ - đừng để khách hàng chờ đợi cả ngày trong khi ứng dụng của bạn tìm ra việc cần làm.
Lưu ý rằng php: // input không khả dụng cho các yêu cầu chỉ định Content-Type: multipart/form-data
tiêu đề ( enctype="multipart/form-data"
ở dạng HTML). Kết quả này từ PHP đã phân tích dữ liệu biểu mẫu vào $_POST
superglobal.
php://input
cũng trống đối với loại application/x-www-form-urlencoded
nội dung (bên cạnh đó multipart/form-data
)
php://input
là. Vì vậy, trong khi các cấu hình CGI (Nhanh) stream_get_contents(STDIN)
sẽ không hoạt động, file_get_contents("php://input")
sẽ.
trả về giá trị trong mảng
$data = json_decode(file_get_contents('php://input'), true);
$data
mảng kết hợp để kiểm tra xem mỗi giá trị được mã hóa theo cách bạn muốn. Cách nhìn "stream-to-datatype" có thể đơn giản, nhưng nó có thể không hiệu quả như xử lý mã hóa trong "dạng luồng" bằng bộ lọc luồng. Nếu bạn không xử lý các vấn đề mã hóa và chỉ đơn giản là vệ sinh và xác nhận, bạn đang thiếu một bước.
Một lý do có thể cho một sản phẩm nào $_POST
đó là yêu cầu không còn POST
hoặc không POST
còn nữa ... Nó có thể đã bắt đầu như một bài đăng, nhưng gặp phải 301
hoặc 302
chuyển hướng ở đâu đó, được chuyển sang GET
!
Kiểm tra $_SERVER['REQUEST_METHOD']
để kiểm tra nếu đây là trường hợp.
Xem https://stackoverflow.com/a/19422232/109787 để biết một cuộc thảo luận tốt về lý do tại sao điều này không nên xảy ra nhưng vẫn còn.
POST
nhưng sau khi kiểm tra nó đã cho thấy rằng nó là GET
. Khi tôi đã thêm một /
ở cuối URL, nó bắt đầu hiển thị POST. Kỳ dị!
Kiểm tra $HTTP_RAW_POST_DATA
biến
php://input
. $HTTP_RAW_POST_DATA
không có sẵn với enctype="multipart/form-data"
.
Nếu bạn đã cài đặt tiện ích mở rộng HTTP PECL, bạn có thể sử dụng http_get_request_body()
hàm để lấy dữ liệu cơ thể dưới dạng chuỗi.
Nếu bạn đã cài đặt tiện ích mở rộng pecl / http , bạn cũng có thể sử dụng tiện ích này:
$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
có false
, thì một mảng trống sẽ được trả về. Nếu ai đó đã gửi XML hoặc YAML thì sao? Thêm một bài kiểm tra cho Kiểu nội dung và đi từ đó.
$_SERVER
superglobal cho các giá trị hữu ích để kiểm tra.
http_get_request_body()
đã được thực hiện rõ ràng để nhận nội dung PUT
và POST
yêu cầu theo tài liệu http://php.net/manual/fa/feft.http-get-request-body.php
$_POST
. Điều này cũng đúng (đặc biệt) trong trường hợp yêu cầu PUT, vì PHP không có siêu lớp tương ứng.