2012-01-20 13 views
167

zgłaszam jako POST do strony php następujące:Jak zdobyć ciało POST w php?

{a:1} 

To ciało wniosek (żądanie POST).
W php, co mam zrobić, aby wyodrębnić tę wartość?

var_dump($_POST); 

nie jest rozwiązaniem, nie działa.

+9

Jest to pytanie pomocne dla osób pragnących tworzyć relaksującego API. Większość nie wie, jak uzyskać dostęp do nieprzetworzonych danych wejściowych przesłanych do ich skryptów, ponieważ nie są one dostępne przez superglobalne '$ _POST'. Jest to również (szczególnie) prawdziwe w przypadku żądań PUT, ponieważ PHP nie ma odpowiadającego superglobalu. – rdlowrey

+4

Możliwy duplikat [Jak uzyskać treść żądania (treść) w PHP?] (Https://stackoverflow.com/questions/7187631/how-to-get-request-content-body-in-php) – YakovL

Odpowiedz

373

Aby uzyskać dostęp do ciała podmiotu urzędu lub umieścić prośbę (lub jakąkolwiek inną metodę HTTP):

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

Również stały STDIN jest już otwarty strumień do php://input, więc można ewentualnie zrobić:

$entityBody = stream_get_contents(STDIN); 

z PHP manual entry on I/O streamsdocs:

php: // input to strumień tylko do odczytu, który umożliwia odczytywanie nieprzetworzonych danych z treści żądania. W przypadku żądań POST lepiej jest użyć , aby użyć php: // input zamiast $HTTP_RAW_POST_DATA, ponieważ nie jest to zależne od specjalnych dyrektyw php.ini. Ponadto w przypadkach, w których $HTTP_RAW_POST_DATA nie jest domyślnie zapełniany, jest to potencjalnie korzystniejsza alternatywa dla aktywowania pamięci od always_populate_raw_post_data. php: // wejście nie jest dostępne z enctype = "multipart/form-data".

W szczególności warto zauważyć, że strumień php://input, niezależnie od tego, jak go otworzyć w SAPI internetowej nie jest możliwy do przeszukania. Oznacza to, że można go odczytać tylko raz. Jeśli pracujesz w środowisku, w którym duże obiekty encji HTTP są rutynowo przesyłane, możesz chcieć zachować dane wejściowe w formie strumienia (zamiast buforować je tak, jak w pierwszym przykładzie powyżej).

Aby utrzymać coś strumień zasobów jak to może być pomocne:

<?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 pozwala zarządzać zużycie pamięci, ponieważ będzie przejrzysty włączyć do systemu plików przechowywania po pewną ilość danych jest przechowywana (2M domyślnie). Tymi rozmiarami można manipulować w pliku php.ini lub dodając /maxmemory:NN, gdzie NN to maksymalna ilość danych przechowywanych w pamięci przed użyciem pliku tymczasowego w bajtach.

Oczywiście, chyba że masz naprawdę dobry powód do szukania strumienia wejściowego, nie powinieneś potrzebować tej funkcji w aplikacji internetowej. Czytanie treści jednostki żądania HTTP raz jest zwykle wystarczające - nie pozwól klientom czekać przez cały dzień, podczas gdy twoja aplikacja wyszuka, co robić.

Uwaga: wejście php: // nie jest dostępne dla żądań określających nagłówek Content-Type: multipart/form-data (enctype="multipart/form-data" w formularzach HTML). Wynika to z faktu, że PHP sparsowało dane formularzy do superglobalu $_POST.

+8

Należy pamiętać, że afaics, strumień STDIN nie jest dostępny w systemach z PHP za pomocą CGI, tj. przez mod_fcgid lub mod_fastcgi itp. – scy

+0

, ale przekazuję zmienną (jako dane formularza) z żądaniem, w jaki sposób mogę uzyskać dostęp do określonej wartości, przekazuję grant_type = hasło i nazwa_użytkownika = użytkownik i hasło = przekazuj jako treść formularza z zapytaniem, w jaki sposób otrzymam grant_type z "$ entityBody" –

+0

zgodnie z moim testem, to 'php: // input' jest puste dla' application/x-www-form -lub-content-type-type (oprócz 'multipart/form-data') – YakovL

2
+5

Preferowaną metodą uzyskiwania dostępu do surowych danych POST jest' php: // input'. '$ HTTP_RAW_POST_DATA' nie jest dostępne z' enctype = "multipart/form-data" '. – nullability

+19

Ta funkcja została ODRADZANA w PHP 5.6.0, a REMOVED od wersji 7.0.0. – Charles

2

Jeżeli masz zainstalowane rozszerzenie PECL HTTP, można skorzystać z funkcji http_get_request_body() aby uzyskać dane ciało jako ciąg.

4

Możliwym powodem jest pusty $_POST, że wniosek nie jest POST, czy nie POST już ... Może to zaczęło się jako post, ale napotkał 301 lub 302 przekierowanie gdzieś, który jest wymagany, aby przełączyć się GET !

Sprawdź, czy nie ma to wpływu na $_SERVER['REQUEST_METHOD'].

+1

To pytanie zadano w kontekście opracowania platformy REST API. –

+0

Nie jestem pewien co masz na myśli? Interfejs API usługi REST może równie dobrze znaleźć przekierowania na swojej ścieżce, to jest kwestia, którą miałem. – Legolas

+0

Miałem na myśli, gdy zadałem pytanie, nie próbowałem rozwiązać problemu, ale raczej próbowałem dowiedzieć się, jak go rozwinąć. –

0

Jeśli masz zainstalowane rozszerzenie pecl/http, można również użyć tego:

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