php $ _POST tablica pusta po przesłaniu formularza

99

Mam niestandardowy CMS, który zbudowałem, który działa doskonale na moim dev boxie (Ubuntu / PHP5 + / MySQL5 +).

Właśnie przeniosłem go do skrzynki produkcyjnej dla mojego klienta i teraz wszystkie przesłane formularze są wyświetlane jako puste tablice $ _POST.

Znalazłem sztuczkę, aby sprawdzić, czy dane są faktycznie przekazywane, file_get_contents('php://input');a dane są tam dobrze widoczne - $_POST/ $_REQUESTarrays są zawsze puste.

Sprawdziłem również, czy nagłówki typu zawartości są poprawne za pomocą firebug ( application/x-www-form-urlencoded; charset=utf-8).

Ten problem występuje niezależnie od tego, czy formularz jest przesyłany przez AJAX, czy zwykły formularz.

Każda pomoc jest mile widziana!


źródło
Sprawdź post_max_size: wartość musi być ustawiona na 8 MB, a nie 8 MB. W ostatnim przypadku nie zobaczysz żadnych błędów, ale rozmiar $ _POST zostanie ustawiony na 0
Siergiej Karpow
Uwaga: Apache wykonuje przekierowanie 301, jeśli brakuje ukośnika.
Leandro

Odpowiedzi:

186

Wiem, że to pytanie dotyczyło POST przez formularz, ale przyszedłem tutaj, szukając odpowiedzi na podobny problem podczas POST z typem zawartości JSON. Znalazłem odpowiedź i chciałem się nią podzielić, ponieważ kosztowało mnie to dużo czasu.

Podczas korzystania z typu zawartości JSON tablica $ _POST nie zapełni się (tylko w przypadku formularzy wieloczęściowych)

Oto, co zadziałało, aby rozwiązać problem:

$rest_json = file_get_contents("php://input");
$_POST = json_decode($rest_json, true);

mam nadzieję, że to komuś pomoże!

tiltem
źródło
1
To obejście ma sens - naprawiło mój kontroler aktualizacji zbiorczej :)
Martin Zeitler
2
Inną alternatywą jest zmiana Content-Typenagłówka na, application/x-www-form-urlencodeda następnie serializacja danych za pomocą $.param(dataObject). To powinno pomóc.
Łukasz Bachman
1
@ ŁukaszBachman Jak zrobić, że jeśli jest coś takiego jak DataObject ........ title=something&body=anything. Chcę zdobyć tytuł i ciało. $ dataobject ["tytuł"] zwraca puste. W moim przypadku $ _POST jest puste. I jedyny sposób, aby to uzyskać za pomocą file_get_contents ("php: // input") ... poza tym, że nie jest zakodowany w formacie JSON.
Khurshid Alam
To jest bardzo przydatne. Dziwne jest to, że nie mam problemu z wysłaniem Json na moją maszynę deweloperską, ale robię to na wersję produkcyjną.
Simon H
86

Oto kolejna możliwa przyczyna - mój formularz był przesyłany do domain.com bez WWW. i skonfigurowałem automatyczne przekierowanie, aby dodać „WWW”. W tym procesie tablica $ _POST była opróżniana. Aby to naprawić, wystarczyło przesłać do www.domain.com


źródło
24
Cholera, przepisanie adresu URL w moim htaccessbyło przyczyną niedziałania POST. Automatycznie dodawałem ukośnik do wszystkich adresów URL, ale w kodzie jako AKCJI użyłem adresu URL bez ukośnika. Twoja odpowiedź pomogła, ponieważ nigdy nie pomyślałem, żeby sprawdzić .htaccess. +1
binar
Miałem przekierowanie domeny (z maskowaniem) za pomocą GoDaddy i wydaje się, że jest to źródłem problemu. Dzięki!
Chris Prince,
1
Miałem też podobny problem, pochodził z mojego .htaccesspliku. To było usuwanie .phprozszerzenia z adresu URL, a mój formularz był POSTna adres URL z rozszerzeniem.
Emanuel Vintilă
25

Miałem podobny problem. Okazało się, że to prosta poprawka. W formie, którą miałem

<form action = "directory" method = "post">

gdzie katalog to nazwa ... katalogu. Moja tablica POST była całkowicie pusta. Kiedy spojrzałem na adres URL w przeglądarce, został wyświetlony z ukośnikiem na końcu.

Dodanie ukośnika do końca mojej akcji załatwiło sprawę -

<form action = "directory /" method = "post">

Moja tablica $ _POST była znowu pełna!

Randy Kilwag
źródło
1
To nie powinno być poprawką, na przykład na CakePHP, który ma dobry system routingu, nie powiódł się (nie mam na myśli błędu Cake), może podejście do tego problemu nie jest oparte na frameworku lub plikach .php, ale trochę konfiguracji na Apache, chciałbym dokładniej zbadać ten problem. To całkiem interesujące.
James
Z podobnej notatki miałem ten sam problem co OP, ale tylko wtedy, gdy <form>tag nie miał nameatrybutu i tylko w IE.
jkt123
13

Upewnij się, że w php.ini:

  • track_vars (jest dostępny tylko w bardzo starych wersjach PHP) jest ustawiony na On
  • variables_order zawiera list P
  • post_max_size jest ustawiony na rozsądną wartość (np. 8 MB)
  • (jeśli używasz plastra suhosin) suhosin.post.max_varsi suhosin.request.max_varssą wystarczająco duże.

Przypuszczam, że druga moja sugestia rozwiąże twój problem.

MrMage
źródło
1
Dzięki MrMage, doceniam twój wgląd i sprawdzę te ustawienia ini i poinformuję cię, czy to załatwiło sprawę. Dzięki!
1
Ustawienie „post_max_size” to mój showstopper. Przesyłałem duży plik podczas przesyłania formularza, a to ustawienie zawierało mniejszą wartość. Więc otrzymuję pustą tablicę postów, kiedy przesyłam formularz.
shasi kanth
9

Odkryłem, że podczas wysyłania z HTTP do HTTPS, $_POSTjest pusty. Stało się to podczas testowania formularza, ale zajęło mi trochę czasu, zanim zdałem sobie z tego sprawę.

Marcos
źródło
5

Natknąłem się na podobny, ale nieco inny problem i zrozumienie problemu zajęło 2 dni.

  • W moim przypadku również tablica POST była pusta.

  • Następnie sprawdzone za pomocą file_get_contents ('php: // input'); i to też było puste.

Później odkryłem, że przeglądarka nie prosiła o potwierdzenie ponownego przesłania danych formularza po odświeżeniu strony załadowanej po przesłaniu POST. To była bezpośrednio odświeżająca strona. Ale kiedy zmieniłem adres URL formularza na inny, poprawnie przekazywał POST i poprosiłem o ponowne przesłanie danych przy próbie odświeżenia strony.

Następnie sprawdziłem, co jest nie tak z rzeczywistym adresem URL. Nie było błędu w adresie URL, jednak wskazywał on na folder bez index.php w adresie URL i sprawdzałem POST na index.php.

Tutaj wątpiłem, że przekierowanie z / do /index.php powoduje utratę danych POST i przetestowałem adres URL z dołączeniem index.php do adresu URL.

To się udało.

Opublikowałem go tutaj, aby ktoś uznał go za pomocny.

GUIR
źródło
1
Miałem ten sam problem, bez '/' na końcu adresu URL, nic nie istnieje w $ _REQUEST, ale z '/' lub '/index.php', wszystkie opublikowane dane znajdują się w $ _REQUEST. To może być moje ustawienia nginx lub coś innego!
MohaMad
5

Jeśli piszesz do pliku index.php w katalogu na przykład /api/index.php upewnij się, że w swoim formularzu podajesz pełny katalog do pliku np.

To

<form method="post" action="/api/index.php"> 
</form>

LUB

<form method="post" action="/api/"> 
</form>

Pracuje.

Ale to zawodzi

<form method="post" action="/api"> 
</form>
Niedziela G Akinsete
źródło
Właściwie mam dokładnie odwrotnie. Odkryłem, że /my_urito zadziała, ale nie /my_uri/.
Link14
1
miał ten sam problem. wygląda na to, że apache lub nginx dodają przekierowanie z / api do / api /
John Smith
Apache wykonuje automatyczne przekierowanie 301, jeśli brakuje ukośnika. Dziękuję za odpowiedź i komentarze też są przydatne.
Leandro
4

Nie mam w tej chwili eleganckiego rozwiązania, ale chciałem podzielić się moimi odkryciami w celu odniesienia się w przyszłości do innych osób, które napotkają ten problem. Źródłem problemu były 2 nadpisane wartości php w pliku .htaccess. Po prostu dodałem te 2 wartości, aby zwiększyć limit rozmiaru pliku dla przesyłania plików z domyślnego 8 MB do czegoś większego - zauważyłem, że po prostu posiadanie tych 2 wartości w pliku htaccess, niezależnie od tego, czy są większe, czy mniejsze niż domyślne, spowodowało problem .

php_value post_max_size xxMB
php_value upload_max_filesize xxMB

Dodałem dodatkowe zmienne, aby, mam nadzieję, podnieść limity dla wszystkich zmiennych suhosin.post.xxx/suhosin.upload.xxx, ale niestety nie przyniosły one żadnego efektu.

Podsumowując, tak naprawdę nie mogę tutaj wyjaśnić „dlaczego”, ale zidentyfikowałem podstawową przyczynę. Mam wrażenie, że jest to ostatecznie problem suhosin / htaccess, ale niestety taki, którego nie byłem w stanie rozwiązać, poza usunięciem 2 nadpisanych wartości php powyżej.

Mam nadzieję, że to pomoże komuś w przyszłości, ponieważ zabiłem kilka godzin, zastanawiając się nad tym. Dziękuję wszystkim, którzy poświęcili mi czas, aby mi w tym pomóc (MrMage, Andrew)


źródło
Warto zadać to pytanie w sprawie Serverfault, szczególnie jeśli problem dotyczy konfiguracji serwera / htaccess.
David mówi, że przywróć Monikę
5
Jeśli się nie mylę, rozmiar powinien być określony jako „xxM”, a nie „xxMB”, więc zastanawiam się, czy to może mieć z tym coś wspólnego ...
JC Inacio,
4

Mogłem rozwiązać ten problem, używając enctype = "application / x-www-form-urlencoded", ponieważ domyślnym ustawieniem jest "text / plain". Kiedy wpisujesz $ DATA separatorem jest spacja na "tekst / zwykły" i specjalny znak na "urlencoded".

Z poważaniem Frank

RudeUrm
źródło
4

Wyłączenie enable_post_data_readingustawienia spowoduje to. Zgodnie z dokumentacją:

enable_post_data_reading

Wyłączenie tej opcji powoduje, że $ _POST i $ _FILES nie są wypełniane. Jedynym sposobem na odczytanie postdata będzie wtedy opakowanie strumienia wejściowego php: //. Może to być przydatne w przypadku żądań proxy lub przetwarzania danych POST w sposób oszczędzający pamięć.

Luke A. Leber
źródło
4
<form action="test.php" method="post">
                        ^^^^^^^^^^^^^

Okej, to było głupie i będę się publicznie zawstydzać, ale odpaliłem mały skrypt testowy dla czegoś w PHP i kiedy moja $_POSTtablica była pusta, StackOverflow to pierwsze miejsce, w którym szukałem i nie znalazłem odpowiedzi, której potrzebowałem .

Tylko napisałem

<form action="test.php">

i zapomniałem określić metody jako istnienie POST!

Jestem pewien, że ktoś będzie chichotał, ale jeśli to pomoże komuś, kto robi to samo, to nie mam nic przeciwko! Wszyscy to robimy od czasu do czasu!

Ivan
źródło
Nie mogę uwierzyć, że też o tym zapomniałem! Próbuję tylko nowego serwera i pomyślałem, że to coś z powodu konfiguracji ... w każdym razie, dzięki za przypomnienie!
Samuel Aiala Ferreira
4

W moim przypadku, podczas wysyłania z HTTP do HTTPS, $ _POST jest pusty. Problem polegał na tym, że formularz miał taką akcję //example.com. Kiedy poprawiłem adres URL na https://example.com , problem zniknął.

Игорь Носков
źródło
1
Myślę, że jest coś związanego z konfiguracją serwera. Mam te same problemy podczas używania GoDaddy jako hosta. To rozwiązanie nie rozwiązało problemu.
acarlstein
To rozwiązanie rozwiązało mój problem. Miałem fajny headeach.
gokaysatir
3

ten sam problem tutaj!

Próbowałem połączyć się z kodem mojego lokalnego serwera za pomocą żądania pocztowego w listonoszach i ten problem zmarnował dużo czasu!

dla każdego, kto używa projektu lokalnego (np. listonosz): użyj swojego adresu IPv4 (wpisz ipconfig w cmd) zamiast słowa kluczowego „localhost”. w moim przypadku:

przed:

localhost/app/login

po:

192.168.1.101/app/login
Ali Shariati
źródło
Postman podał mi kilka problemów z pobranymi wartościami json, które mają cudzysłowy lub spacje. Oczekuje określonego formatu.
Tom Anderson,
2

ODNIESIENIE: http://www.openjs.com/articles/ajax_xmlhttp_using_post.php

Metoda POST

Zamierzamy wprowadzić pewne modyfikacje, więc przy wysyłaniu zapytania wykorzystana zostanie metoda POST ...

var url = "get_data.php";
var params = "lorem=ipsum&name=binny";
http.open("POST", url, true);

//Send the proper header information along with the request
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.setRequestHeader("Content-length", params.length);
http.setRequestHeader("Connection", "close");

http.onreadystatechange = function() {//Call a function when the state changes.
  if(http.readyState == 4 && http.status == 200) {
    alert(http.responseText);
  }
}
http.send(params);

Niektóre nagłówki http należy ustawić wraz z każdym żądaniem POST. Więc umieściliśmy je w tych liniach ...

http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.setRequestHeader("Content-length", params.length);
http.setRequestHeader("Connection", "close");

W powyższych wierszach w zasadzie mówimy, że dane przesyłane są w formacie formularza. Podajemy również długość wysyłanych przez nas parametrów.

http.onreadystatechange = function() {//Call a function when the state changes.
  if(http.readyState == 4 && http.status == 200) {
    alert(http.responseText);
  }
}

Ustawiliśmy procedurę obsługi dla zdarzenia zmiany stanu gotowości. To jest ten sam program obsługi, którego użyliśmy dla metody GET. Możesz użyć http.responseText tutaj - wstawić do div za pomocą innerHTML (AHAH), eval it (JSON) lub cokolwiek innego.

http.send(params);

Na koniec wysyłamy parametry z żądaniem. Podany adres URL jest ładowany dopiero po wywołaniu tej linii. W metodzie GET parametr będzie miał wartość null. Ale w metodzie POST dane do wysłania zostaną przesłane jako argument funkcji send. Zmienna params została zadeklarowana w drugiej linii jako lorem=ipsum&name=binny- więc wysyłamy dwa parametry - „lorem” i „name” z odpowiednio wartościami „ipsum” i „binny”.

Chandu
źródło
1

W moim przypadku było to spowodowane tym, że użyłem jQuery do wyłączenia wszystkich danych wejściowych na stronie tuż przed użyciem jQuery do przesłania formularza. Więc zmieniłem moje „wyłącz każde wejście, nawet„ ukryte ”typy”:

$(":input").attr("disabled","disabled"); 

aby „wyłączyć tylko wejścia typu„ przycisk ””:

$('input[type=button]').attr('disabled',true);

To było tak, że użytkownik nie mógł przypadkowo dwukrotnie nacisnąć przycisku „start” i podłączyć naszego DB! Wygląda na to, że jeśli umieścisz atrybut „wyłączony” w formularzu wejściowym typu „ukryty”, ich wartości nie zostaną przesłane po przesłaniu formularza!

Josh P
źródło
1

Dla mnie .htaccess przekierowywał, gdy mod_rewrite nie był zainstalowany. Zainstaluj mod_rewite i wszystko jest w porządku.

Konkretnie:

<IfModule !mod_rewrite.c>
  ErrorDocument 404 /index.php
</Ifmodule>

wykonywał.

Martin Fisher
źródło
1

Właśnie spędziłem godziny, aby rozwiązać podobny problem. Problemem w moim przypadku był plik

max_input_vars = "1000"

domyślnie w php.ini. Miałem naprawdę ogromną formę bez uploadów. php.ini jest ustawione na upload_max_filesize = "100M" i post_max_size = "108M" iz pewnością nie był to problem w moim przypadku. Zachowanie PHP jest takie samo dla max_input_vars, gdy przekracza 1000 zmiennych w formularzu. Zwraca i pustą tablicę _POST. Żałuję, że nie mogłem znaleźć tego godzinę i godziny temu.

MyraGe
źródło
1

Wiem, że to stare, ale chciałem podzielić się moim rozwiązaniem.

W moim przypadku problem dotyczył mojego .htaccess, ponieważ dodałem zmienne, aby podnieść maksymalny limit wysyłania PHP. Mój kod wyglądał tak:

php_value post_max_size 50MB
php_value upload_max_filesize 50MB

Później zauważam, że wartości powinny być takie jak xxM, a nie xxMB i kiedy zmieniłem to na:

php_value post_max_size 50M
php_value upload_max_filesize 50M

teraz mój $ _POST zwrócił dane jak zwykle wcześniej. Mam nadzieję, że to pomoże komuś w przyszłości.

Walid Ajaj
źródło
0

Oprócz postu MRMage:

Musiałem ustawić tę zmienną, aby rozwiązać problem polegający na tym, że niektóre $_POSTzmienne (z dużą tablicą> 1000 pozycji) zniknęły:

suhosin.request.max_vars = 2500

Rozwiązaniem było „ request”, a nie „ post” ...

Itzekocke Setzling
źródło
0

Być może nie jest to najwygodniejsze rozwiązanie, ale doszedłem do wniosku, że jeśli ustawię actionatrybut formularza na domenę główną, można uzyskać dostęp do index.php i pobrać opublikowane zmienne. Jeśli jednak ustawię przepisany adres URL jako akcję, to nie zadziała.

Rápli András
źródło
0

Jest to trochę podobne do tego, co powiedział @icesar .

Ale próbowałem wysyłać rzeczy do mojego interfejsu API, znajdującego się w site/api/index.php, tylko wysyłając do, site/apiponieważ jest przekazywany index.phpsamodzielnie. To jednak najwyraźniej powoduje, że coś się zepsuło, ponieważ mój $_POSTzostał opróżniony w locie. Po prostu wysłanie do site/api/index.phpbezpośrednio zamiast tego rozwiązało.

Victor Häggqvist
źródło
0

Mój problem polegał na tym, że użyłem <base>tagu HTML do zmiany podstawowego adresu URL mojej witryny testowej. Po usunięciu tego tagu z nagłówka $_POSTdane wróciły.

Ben
źródło
0

W moim przypadku (strona php na serwerze wzajemnym OVH) enctype="text/plain"nie działa ( $_POSTa odpowiadająca jej strona $_REQUESTjest pusta), pozostałe przykłady poniżej działają. `

<form action="?" method="post">
<!-- in this case, my google chrome 45.0.2454.101 uses -->
<!--     Content-Type:application/x-www-form-urlencoded -->
    <input name="say" value="Hi">
    <button>Send my greetings</button>
</form>

<form action="?" method="post" enctype="application/x-www-form-urlencoded">
    <input name="say" value="Hi">
    <button>Send my application/x-www-form-urlencoded greetings</button>
</form>

<form action="?" method="post"  enctype="multipart/form-data">
    <input name="say" value="Hi">
    <button>Send my multipart/form-data greetings</button>
</form>

<form action="?" method="post" enctype="text/plain"><!-- not working -->
    <input name="say" value="Hi">
    <button>Send my text/plain greetings</button>
</form>

`

Więcej tutaj: method = "post" enctype = "text / plain" nie są zgodne?

PaulH
źródło
0

Otrzymałem następujący błąd z Mod Security:

Access denied with code 500 (phase 2). Pattern match "((select|grant|delete|insert|drop|alter|replace|truncate|update|create|rename|describe)[[:space:]]+[A-Z|a-z|0-9|\*| |\,]+[[:space:]]+(from|into|table|database|index|view)[[:space:]]+[A-Z|a-z|0-9|\*| |\,]|UNION SELECT.*\'.*\'.*,[0-9].*INTO.*FROM)" at REQUEST_BODY. [file "/usr/local/apache/conf/modsec2.user.conf"] [line "345"] [id "300013"] [rev "1"] [msg "Generic SQL injection protection"] [severity "CRITICAL"]

Po usunięciu konfiguracji zabezpieczeń modów do przetestowania wszystko działało zgodnie z oczekiwaniami. Teraz muszę tylko zmodyfikować moje reguły, aby były bezpieczne, ale wystarczająco elastyczne dla moich potrzeb :)

Łukasz
źródło
0

Upewnij się, że używasz name = " twoja_nazwa_zmiennej " w tagu wejściowym.

Błędnie użyłem id = " twoja_nazwa_zmiennej ".

Spędziłem dużo czasu, aby złapać błąd.

Frank Hsieh
źródło
0

Upewnij się, że namewłaściwość każdego pola jest zdefiniowana.

Spowoduje to utworzenie pustego POST w PHP

<input type="text" id="Phone">

Ale to zadziała

<input type="text" name="Phone" id="Phone">
Miguel Montes de Oca
źródło
Myślę, że jest coś związanego z konfiguracją serwera. Mam te same problemy podczas używania GoDaddy jako hosta. To rozwiązanie nie rozwiązało problemu.
acarlstein
-1

OK, pomyślałem, że powinienem umieścić tutaj mój przypadek .... Otrzymałem pustą tablicę wiadomości w określonych przypadkach .. Formularz działa dobrze, ale czasami użytkownicy narzekają, że kliknęli przycisk Prześlij i nic się nie dzieje .... Po pewnym czasie odkryłem, że moja firma hostingowa ma moduł bezpieczeństwa, który sprawdza dane wejściowe użytkowników i czyści całą tablicę postów (nie tylko złośliwe dane), jeśli to wykryje. W moim przykładzie nauczyciel matematyki próbował wprowadzić równanie: dy + dx + 0 = 0; a dane zostały całkowicie usunięte.

Aby to naprawić, radzę mu po prostu teraz wprowadzić dane w polu tekstowym jako dy + dx + 0 = zero, a teraz działa ... To może zaoszczędzić komuś trochę czasu ..

Mahmoud Elgabry
źródło
5
Proszenie użytkowników o uwzględnienie wadliwego kodu nie jest możliwe.
freeworlder
To naprawdę nie jest błędny kod, ale możesz rozważyć nowego dostawcę hostingu. Alternatywnie opublikuj dane wejściowe w innej formie, np. Z kodowaniem HTML URL.
Tom Anderson