Tableau php $ _POST vide lors de la soumission du formulaire


99

J'ai un CMS personnalisé que j'ai construit qui fonctionne parfaitement sur ma boîte de développement (Ubuntu / PHP5 + / MySQL5 +).

Je viens de le déplacer vers la boîte de production de mon client et maintenant toutes les soumissions de formulaire apparaissent sous forme de tableaux $ _POST vides.

J'ai trouvé une astuce pour vérifier que les données sont effectivement transmises file_get_contents('php://input');et que les données s'affichent bien là-bas - les tableaux $_POST/ $_REQUESTsont toujours vides.

J'ai également vérifié que les en-têtes de type de contenu sont également corrects via firebug ( application/x-www-form-urlencoded; charset=utf-8).

Ce problème se produit indépendamment du fait qu'un formulaire soit soumis via AJAX ou un formulaire normal.

Toute aide est grandement appréciée!

php  arrays  forms  post 

Vérifiez post_max_size: la valeur doit être définie sur 8 Mo et non sur 8 Mo. Dans le dernier cas, vous ne verrez aucune erreur, mais la taille de $ _POST sera définie sur 0
Sergei Karpov

Attention: Apache effectue une redirection 301 s'il manque une barre oblique.
Leandro le

Réponses:


186

Je sais que cette question concernait POST via un formulaire, mais je suis venu ici à la recherche de réponses à un problème similaire lors de la publication avec le type de contenu JSON. J'ai trouvé la réponse et j'ai voulu la partager car cela m'a coûté beaucoup de temps.

Lors de l'utilisation de type de contenu JSON, le tableau $ _POST ne se remplira pas (uniquement avec des formulaires en plusieurs parties, je crois)

Voici ce qui a fonctionné pour corriger le problème:

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

espérons que cela aide quelqu'un!


1
Cette solution de contournement a du sens - elle a corrigé mon contrôleur de mise à jour par lots :)
Martin Zeitler

2
Une autre alternative consiste à changer l'en- Content-Typetête application/x-www-form-urlencodedet à sérialiser vos données avec $.param(dataObject). Cela devrait aider.
ŁukaszBachman

1
@ ŁukaszBachman Comment faire si dataobject est quelque chose comme ........ title=something&body=anything. Je veux avoir la valeur du titre et du corps. $ dataobject ["title"] renvoie vide. Dans mon cas, $ _POST est vide. Et le seul moyen de l'obtenir en utilisant file_get_contents ("php: // input") ... sauf qu'il n'est pas encodé en json.
Khurshid Alam

Ceci est très utile. Ce qui est étrange, c'est que je n'ai aucun problème avec l'envoi de Json sur ma machine de développement, mais sur celle de production.
Simon H


86

Voici une autre cause possible - mon formulaire était soumis à domain.com sans le WWW. et j'avais mis en place une redirection automatique pour ajouter le "WWW". Le tableau $ _POST était vidé dans le processus. Donc, pour résoudre ce problème, tout ce que j'avais à faire était de me soumettre à www.domain.com


24
htaccessBon sang , une réécriture d'url dans mon était la cause du dysfonctionnement des POST. J'ajoutais automatiquement une barre oblique à toutes les URL, mais dans le code comme ACTION, j'utilisais une URL sans barre oblique. Votre réponse a aidé, car je n'ai jamais pensé à vérifier le .htaccess. +1
binar

J'ai eu le transfert de domaine (avec masquage) en utilisant Godaddy, et cela semble être la source du problème.Merci!
Chris Prince

1
J'ai également eu un problème similaire, il provenait de mon .htaccessdossier. Il supprimait l' .phpextension de l'URL et mon formulaire était POSTdirigé vers l'URL avec l'extension.
Emanuel Vintilă

25

J'avais un problème similaire. S'est avéré être une solution simple. Sous la forme que j'avais

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

où répertoire était le nom de ... le répertoire. Mon tableau POST était totalement vide. Lorsque j'ai regardé l'URL dans mon navigateur, elle était affichée avec une barre oblique à la fin.

L'ajout de la barre oblique à la fin de mon action a fait l'affaire -

<form action = "répertoire /" method = "post">

Mon tableau $ _POST était à nouveau plein!


1
Cela ne devrait pas être un correctif, par exemple sur CakePHP, qui a un bon système de routage, a échoué sur ce point, (je ne veux pas dire que Cake a échoué), peut-être que l'approche de ce problème n'est pas le framework ou les fichiers .php, mais quelques config sur apache, j'aimerais faire une enquête plus approfondie sur ce problème. C'est assez intéressant.
James

Sur une note similaire, j'ai eu le même problème que l'OP, mais seulement si la <form>balise n'avait pas d' nameattribut, et uniquement dans IE.
jkt123

13

Assurez-vous que, dans php.ini:

  • track_vars (il n'est disponible que sur les très anciennes versions de PHP) est défini sur On
  • variables_order contient la lettre P
  • post_max_size est réglé sur une valeur raisonnable (par exemple 8 Mo)
  • (si vous utilisez un patch suhosin) suhosin.post.max_varset suhosin.request.max_varssont suffisamment grands.

Je suppose que ma deuxième suggestion résoudra votre problème.


1
Merci MrMage, appréciez votre perspicacité et vérifiera ces paramètres ini et vous fera savoir si cela a fonctionné. Merci!

1
Le paramètre "post_max_size" est mon showstopper. J'étais en train de télécharger un gros fichier lors de la soumission du formulaire et ce paramètre contenait une valeur inférieure. Je reçois donc un tableau de messages vide lorsque je soumets le formulaire.
shasi kanth

9

J'ai constaté que lors de la publication de HTTP vers HTTPS, le $_POSTfichier est vide. Cela s'est produit lors du test du formulaire, mais cela m'a pris du temps avant de m'en rendre compte.


5

Je suis tombé sur un problème similaire mais légèrement différent et il a fallu 2 jours pour comprendre le problème.

  • Dans mon cas, le tableau POST était également vide.

  • Puis vérifié avec file_get_contents ('php: // input'); et c'était aussi vide.

Plus tard, j'ai trouvé que le navigateur ne demandait pas de confirmation pour la soumission des données du formulaire après si je rafraîchis la page chargée après la soumission POST. C'était une page directement rafraîchissante. Mais lorsque j'ai changé l'URL du formulaire en une autre, il passait correctement le POST et a demandé à resoumettre les données lors de la tentative d'actualisation de la page.

Ensuite, j'ai vérifié ce qui ne va pas avec l'URL réelle. Il n'y avait aucun défaut avec l'URL, mais il pointait vers un dossier sans index.php dans l'URL et je vérifiais POST à ​​index.php.

Ici, je doutais que la redirection de / vers /index.php entraîne la perte des données POST et teste l'URL avec l'ajout d'index.php à l'URL.

Ça a marché.

Postez-le ici pour que quelqu'un le trouve utile.


1
J'ai eu le même problème, sans '/' à la fin de l'url, rien n'existe dans $ _REQUEST, mais avec '/' ou '/index.php', toutes les données postées existent dans $ _REQUEST. Ce pourrait être mes paramètres nginx ou autre chose!
MohaMad

5

Si vous publiez dans un fichier index.php dans un répertoire par exemple /api/index.php, assurez-vous que dans votre formulaire vous spécifiez le répertoire complet du fichier, par exemple

Ce

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

OU

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

travaux.

Mais cela échoue

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

J'ai en fait exactement le contraire. J'ai découvert que /my_uricela fonctionnerait mais pas /my_uri/.
Link14

1
eu le même problème. il semble qu'apache ou nginx ajoute une redirection de / api vers / api /
John Smith

Apache effectue une redirection automatique 301 si la barre oblique est manquante. Merci pour votre réponse et les commentaires sont également utiles.
Leandro le

4

Je n'ai pas de solution élégante à ce stade, mais je voulais partager mes découvertes pour la future référence d'autres personnes qui rencontrent ce problème. La source du problème était 2 valeurs php remplacées dans un fichier .htaccess. J'avais simplement ajouté ces 2 valeurs pour augmenter la limite de taille de fichier pour les téléchargements de fichiers de 8 Mo par défaut à quelque chose de plus grand - j'ai observé que le simple fait d'avoir ces 2 valeurs dans le fichier htaccess, qu'elles soient plus grandes ou plus petites que la valeur par défaut, causait le problème .

php_value post_max_size xxMB
php_value upload_max_filesize xxMB

J'ai ajouté des variables supplémentaires pour augmenter, espérons-le, les limites de toutes les variables suhosin.post.xxx/suhosin.upload.xxx, mais celles-ci n'ont malheureusement aucun effet sur ce problème.

En résumé, je ne peux pas vraiment expliquer le «pourquoi» ici, mais j'en ai identifié la cause profonde. Mon sentiment est que c'est finalement un problème de suhosin / htaccess, mais malheureusement un problème que je n'ai pas pu résoudre autrement que de supprimer les 2 valeurs php remplacées ci-dessus.

J'espère que cela aidera quelqu'un dans le futur alors que j'ai tué une poignée d'heures à comprendre cela. Merci à tous ceux qui ont pris le temps de m'aider avec ça (MrMage, Andrew)


Cela pourrait valoir la peine de poser cette question sur Serverfault, en particulier si le problème réside dans la configuration du serveur / htaccess.
David dit de réintégrer Monica

5
Si je ne me trompe pas, la taille doit être spécifiée comme `` xxM '', et non `` xxMB '', alors je me demande si cela pourrait avoir quelque chose à voir avec ça ...
JC Inacio

4

Je pourrais résoudre le problème en utilisant enctype = "application / x-www-form-urlencoded" comme la valeur par défaut est "text / plain". Lorsque vous archivez $ DATA, le séparateur est un espace pour "text / plain" et un caractère spécial pour "urlencoded".

Cordialement Frank


4

La enable_post_data_readingdésactivation du paramètre entraînera cela. Selon la documentation:

enable_post_data_reading

La désactivation de cette option fait que $ _POST et $ _FILES ne sont pas remplis. Le seul moyen de lire les données postales sera alors via le wrapper de flux d'entrée php: //. Cela peut être utile pour les requêtes proxy ou pour traiter les données POST de manière efficace en mémoire.


4
<form action="test.php" method="post">
                        ^^^^^^^^^^^^^

D'accord, c'était stupide et je vais m'embarrasser en public, mais j'ai lancé un petit script de test pour quelque chose en PHP et quand mon $_POSTtableau était vide, StackOverflow est le premier endroit où j'ai regardé et je n'ai pas trouvé la réponse dont j'avais besoin .

J'avais seulement écrit

<form action="test.php">

et j'ai oublié de spécifier la méthode comme étant POST!

Je suis sûr que quelqu'un ricanera, mais si cela aide quelqu'un d'autre qui fait la même chose, ça ne me dérange pas! Nous le faisons tous de temps en temps!


Je ne peux pas croire que j'ai oublié ça aussi! J'essaie juste un nouveau serveur, et j'ai pensé que c'était quelque chose en raison de la configuration ... de toute façon, merci pour le rappel!
Samuel Aiala Ferreira

4

Dans mon cas, lors de la publication de HTTP vers HTTPS, le $ _POST est vide. Le problème était que le formulaire avait une action comme celle-ci //example.com Lorsque j'ai corrigé l'URL de https://example.com , le problème a disparu.


1
Je pense que c'est quelque chose lié à la façon dont le serveur est configuré. J'ai les mêmes problèmes en utilisant GoDaddy en tant qu'hôte. Cette solution n'a pas résolu le problème.
acarlstein

Cette solution a résolu mon problème. J'avais une belle tête.
gokaysatir le

3

même problème ici!

J'essayais de me connecter à mon code de serveur local via une demande de poste dans le facteur, et ce problème m'a fait perdre beaucoup de temps!

pour quiconque utilise un projet local (par exemple, postman): utilisez votre adresse IPv4 (tapez ipconfig dans cmd) au lieu du mot-clé "localhost". dans mon cas:

avant:

localhost/app/login

après:

192.168.1.101/app/login

Postman m'a donné quelques problèmes avec les valeurs json grattées qui ont des guillemets ou des espaces. Il attend un format spécifique.
Tom Anderson

2

RÉFÉRENCE: http://www.openjs.com/articles/ajax_xmlhttp_using_post.php

Méthode POST

Nous allons faire quelques modifications donc la méthode POST sera utilisée lors de l'envoi de la requête ...

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);

Certains en-têtes http doivent être définis avec toute requête POST. Alors nous les plaçons dans ces lignes ...

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

Avec les lignes ci-dessus, nous disons essentiellement que les données envoyées sont dans le format d'une soumission de formulaire. Nous donnons également la longueur des paramètres que nous envoyons.

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

Nous définissons un gestionnaire pour l'événement de modification «état prêt». C'est le même gestionnaire que nous avons utilisé pour la méthode GET. Vous pouvez utiliser http.responseText ici - insérer dans un div en utilisant innerHTML (AHAH), eval it (JSON) ou autre chose.

http.send(params);

Enfin, nous envoyons les paramètres avec la requête. L'URL donnée n'est chargée qu'après l'appel de cette ligne. Dans la méthode GET, le paramètre sera une valeur nulle. Mais dans la méthode POST, les données à envoyer seront envoyées comme argument de la fonction d'envoi. La variable params a été déclarée dans la deuxième ligne comme lorem=ipsum&name=binny- nous envoyons donc deux paramètres - «lorem» et «name» avec les valeurs «ipsum» et «binny» respectivement.


1

Dans mon cas, c'était parce que j'utilisais jQuery pour désactiver toutes les entrées de la page juste avant d'utiliser jQuery pour soumettre le formulaire. J'ai donc changé mon "désactiver toutes les entrées même les types" cachés "":

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

pour "désactiver uniquement les entrées de type" bouton "":

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

C'était ainsi l'utilisateur ne pouvait pas accidentellement appuyer deux fois sur le bouton «go» et arroser notre DB! Il semble que si vous mettez l'attribut «désactivé» sur un formulaire de type «caché», leurs valeurs ne seront pas envoyées si le formulaire est soumis!


1

Pour moi, .htaccess redirigeait lorsque mod_rewrite n'était pas installé. Installez mod_rewite et tout va bien.

Plus précisément:

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

était en cours d'exécution.


1

Je viens de passer des heures à résoudre un problème similaire. Le problème dans mon cas, c'était le

max_input_vars = "1000"

par défaut, dans le php.ini. J'avais un formulaire vraiment énorme sans téléchargement. php.ini est défini sur upload_max_filesize = "100M" et post_max_size = "108M" et ce n'était sûrement pas le problème dans mon cas. Le comportement de PHP est le même pour max_input_vars lorsqu'il dépasse 1000 variables dans le formulaire. Il retourne et vide le tableau _POST. J'aurais aimé trouver ça il y a une heure et quelques heures.


1

Je sais que c'est vieux, mais je voulais partager ma solution.

Dans mon cas, le problème était dans mon .htaccess car j'ai ajouté des variables pour augmenter la limite de téléchargement maximale de mon PHP. Mon code était comme ceci:

php_value post_max_size 50MB
php_value upload_max_filesize 50MB

Plus tard, je remarque que les valeurs devraient aimer xxM et non xxMB et quand je l'ai changé en:

php_value post_max_size 50M
php_value upload_max_filesize 50M

maintenant, mon $ _POST a renvoyé les données comme d'habitude auparavant. J'espère que cela aidera quelqu'un à l'avenir.


0

En plus du message de MRMage:

J'ai dû définir cette variable pour résoudre le problème de la $_POSTdisparition de certaines variables (avec un grand tableau> 1000 éléments):

suhosin.request.max_vars = 2500

" request", pas " post" était la solution ...


0

Ce n'est peut-être pas la solution la plus pratique, mais j'ai compris que si je définissais l' actionattribut form sur le domaine racine, index.php était accessible et obtenait les variables publiées. Cependant, si je définis une URL réécrite comme action, cela ne fonctionne pas.


0

C'est un peu similaire à ce que dit @icesar .

Mais j'essayais de publier des trucs sur mon api, situé dans site/api/index.php, en ne postant que site/apicar il est transmis index.phppar lui-même. Cependant, cela a apparemment gâché quelque chose, car mon a $_POSTété vidé à la volée. Le simple fait de poster site/api/index.phpdirectement à la place l'a résolu.


0

Mon problème était que j'utilisais la <base>balise HTML pour modifier l'URL de base de mon site de test. Une fois que j'ai supprimé cette balise de l'en-tête, les $_POSTdonnées sont revenues.


0

Dans mon cas (page php sur le serveur OVH mutualisé) enctype="text/plain"ne fonctionne pas ( $_POSTet correspondant $_REQUESTest vide), les autres exemples ci-dessous fonctionnent. »

<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>

»

Plus ici: method = "post" enctype = "text / plain" ne sont pas compatibles?


0

J'obtenais l'erreur suivante de 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"]

Une fois que j'ai supprimé ma configuration de sécurité mod pour tester, tout a fonctionné comme prévu. Maintenant, j'ai juste besoin de modifier mes règles pour rester en sécurité mais suffisamment flexible pour mes besoins :)


0

Assurez-vous d'utiliser name = " your_variable_name " dans la balise d'entrée.

J'utilise par erreur id = " your_variable_name ".

J'ai passé beaucoup de temps à attraper le bogue.


0

Assurez-vous que la namepropriété de chaque champ est définie.

Cela vous crée un POST vide sur PHP

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

Mais cela fonctionnera

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

Je pense que c'est quelque chose lié à la façon dont le serveur est configuré. J'ai les mêmes problèmes en utilisant GoDaddy en tant qu'hôte. Cette solution n'a pas résolu le problème.
acarlstein

-1

OK, je pensais que je devrais mettre mon cas ici ... J'étais en train de vider le tableau de messages dans des cas spécifiques ... Le formulaire fonctionne bien, mais parfois les utilisateurs se plaignent d'avoir appuyé sur le bouton Soumettre, et rien ne se passe ... Après avoir creusé pendant un moment, j'ai découvert que ma société d'hébergement dispose d'un module de sécurité qui vérifie les entrées des utilisateurs et efface tout le tableau de messages (pas seulement les données malveillantes) s'il le découvre. Dans mon exemple, un professeur de mathématiques essayait de saisir l'équation: dy + dx + 0 = 0; et les données ont été complètement effacées.

Pour résoudre ce problème, je lui conseille simplement maintenant de saisir les données dans la zone de texte comme dy + dx + 0 = zéro, et maintenant cela fonctionne .... Cela peut faire gagner du temps à quelqu'un.


5
Demander aux utilisateurs de tenir compte du code défectueux est un non-démarreur.
freeworlder

Ce n'est pas vraiment un code défectueux, mais vous pourriez envisager un nouveau fournisseur d'hébergement. Vous pouvez également publier l'entrée sous une forme différente, par exemple le codage URL HTML.
Tom Anderson
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.