55 votes

PHP : certaines valeurs $_POST manquent mais sont présentes dans php://input

J'ai un très grand formulaire html (contenant un tableau avec des lignes, qui contiennent plusieurs entrées), que je dois soumettre à PHP script via une requête POST. Le problème est que certaines valeurs ne passent pas et sont absentes dans la superglobale $_POST de PHP.

J'ai vérifié (en utilisant l'extension Firebug) que les valeurs sont effectivement envoyées au serveur par le navigateur.

$_POST est rempli, mais certaines valeurs sont simplement manquantes.

J'ai vérifié ce que la demande brute utilise :

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

et la chaîne retournée a les valeurs. Elles ne sont simplement pas analysées dans le tableau $_POST. La chose étrange que j'ai remarquée, c'est qu'il semble que les valeurs php://input soient coupées après une certaine longueur, et que le reste de la chaîne ne parvienne pas à $_POST.

J'ai pensé à post_max_size et memory_limit et les ai fixés à de grandes valeurs :

memory_limit = 256M
post_max_size = 150M

mais selon la documentation de php $_POST ne devrait pas contenir de valeurs si la requête faite est plus grande que post_max_size.

En raison de la taille importante du formulaire et de la demande, je ne peux pas le poster ici, mais je peux poster le php script que j'ai utilisé pour déboguer le problème :

var_dump($file = file_get_contents('php://input'));
var_dump($_POST);
//... then i parsed the $file

Version du serveur : Apache/2.2.9 (Debian)
Version PHP : PHP 5.3.2-0.dotdeb.2

Quelqu'un peut-il expliquer la raison de ce comportement étrange de PHP, et que dois-je faire (changer les paramètres de php, le code ?) pour utiliser le tableau $_POST pendant le traitement du formulaire ?

EDIT : Pour être clair : il n'y a pas que les valeurs qui manquent. $_POST ne contient pas non plus ces clés.

e.x. fragment de poste brut :

t_dodparam%5B198%5D=&t_dodparam2%5B198%5D=&t_kolejnosc%5B198%5D=199&n_indeks=201&n_wartosc=testtesttest

La clé 't_dodparam' est dans le poste et a la clé 198. Le reste des paramètres est manquant (par exemple, t_dodparam2 est dans post, mais il n'a pas de clé comme 198, et il n'y a pas de clé comme n_wartosc dans $_POST).

1 votes

Pouvez-vous nous donner un exemple d'une valeur de paramètre manquante ?

0 votes

Voici le fragment de message brut : t_dodparam%5B198%5D=&t_dodparam2%5B198%5D=&t_kolejnosc%5B198%5D=199&n_indeks=201&n_wartosc=testtest. t_dodparam[198] est dans les valeurs du message mais le reste est manquant

1 votes

Le signe "&" ne signale-t-il pas la fin d'un paramètre et le début d'un nouveau ?

33voto

felixsigl Points 1512

PHP modifie les champs contenant les caractères espace, point, crochet ouvert et autres pour les rendre compatibles avec l'ancienne méthode register_globals.

vous pouvez trouver beaucoup de solutions de contournement dans les commentaires ici : PHP : Variables provenant de sources externes

Par exemple (commentaire du POSTer) :

<?php
//Function to fix up PHP's messing up POST input containing dots, etc.
function getRealPOST() {
    $pairs = explode("&", file_get_contents("php://input"));
    $vars = array();
    foreach ($pairs as $pair) {
        $nv = explode("=", $pair);
        $name = urldecode($nv[0]);
        $value = urldecode($nv[1]);
        $vars[$name] = $value;
    }
    return $vars;
}
?>

0 votes

Merci, c'est exactement ce que j'ai fait et cela résout le problème, (comme une solution de contournement) mais je ne sais toujours pas quelle est la cause. Je pense que les crochets ne devraient pas poser de problème puisque de nombreux formulaires html utilisent la syntaxe des tableaux (ex. <input name="user[1]" type="text" /> ). Cela fonctionne bien dans ce formulaire ($_POST['t_dodparam'][198] existe et est égal à ""), mais les données d'entrée sont coupées après celui-ci.

0 votes

Vous avez raison, c'est un comportement vraiment fou ! avez-vous déjà vérifié max_input_time et max_execution_time ?

1 votes

C'était un problème de max_input_time. Merci beaucoup !

33voto

Juanita Points 101

Je viens de résoudre ce problème en ajoutant une valeur à max_input_vars dans mon fichier de configuration PHP. D'après este . il a été introduit dans la version 5.3.9, mais après quelques mises à jour de paquets, j'ai rencontré ce problème dans la version 5.3.2.

La valeur par défaut de max_input_vars est de 1000, ce qui était trop faible pour mon formulaire.

0 votes

Notez que cette variable ne peut pas être définie au moment de l'exécution :(

0 votes

Voici la réponse que je cherchais. Merci.

2 votes

S'il vous manque simplement des variables dans POST, et que vous avez un formulaire très volumineux, c'est probablement la réponse.....

12voto

Dalin Points 665

Il y a beaucoup de choses différentes qui peuvent causer cela. Le mieux est de vérifier votre journal d'erreurs. La plupart des choses qui causent ce symptôme affichent des messages dans le journal des erreurs, mais n'affichent pas d'erreurs dans votre application PHP.

Certaines des causes possibles :

Suhosin

Suhosin est une extension pour PHP conçue pour protéger les serveurs et les utilisateurs contre les failles connues et inconnues des applications PHP et du noyau PHP. Elle limite notamment la taille des champs $_POST, $_GET, $_REQUEST et $_COOKIE. Si votre problème est lié à Suhosin, vous obtiendrez une erreur dans votre journal telle que

ALERTE - la limite de la variable POST configurée est dépassée - la variable 'foo' a été supprimée.

La solution est simple, il suffit d'augmenter le nombre maximum de variables autorisées dans le php.ini. Si vous n'avez pas de section suhosin, créez-en une. Comme ceci :

[suhosin]
suhosin.request.max_vars = 1000 # Default is 200
suhosin.post.max_vars = 1000 # Default is 200

Il y a d'autres paramètres de suhosin qui peuvent causer cela, mais ce sont les candidats les plus probables.

Noms de champs de formulaire non valides

Dans le passé, PHP avait un paramètre appelé register_globals (maintenant déprécisé) qui convertissait automatiquement les variables GET et POST en variables PHP. Ainsi, si votre formulaire contient les champs 'foo' et 'bar', lorsque ce formulaire est soumis, les variables $foo et $bar sont automatiquement créées. Cependant, il existe plusieurs caractères qui ne sont pas valides pour être utilisés dans les noms de variables PHP (espace, point, crochet ouvert et autres). Selon les caractères que vous avez utilisés, la variable peut avoir les caractères non valides supprimés, avoir une valeur manquante ou être désactivée. Malgré le fait que register_globals ne soit plus utilisé, PHP supprime toujours ces caractères lors de la construction de $_POST, $_GET, $_REQUEST et $_COOKIE. Si vous ne parvenez pas à fixer les valeurs des champs du formulaire, vous pouvez essayer quelque chose comme :

<?php
/**
 * Converts raw POST data into an array.
 * 
 * Does not work for hierarchical POST data.
 *
 * @return array
 */
function real_post() {
  static $post;
  if (!isset($post)) {
    $pairs = explode("&", file_get_contents("php://input"));
    $post = array();
    foreach ($pairs as $pair) {
      $x = explode("=", $pair);
      $post[rawurldecode($x[0])] = rawurldecode($x[1]);
    }
  }
  return $post;
}
?>

0 votes

En fait, un point dans le nom a causé des problèmes avec ma variable $_POST. Merci @Dalin

10voto

xavividal Points 11

Et si on utilisait "parse_str" pour convertir la chaîne de requête en structures php ? Cette fonction est l'inverse de http_build_query.

    $b = array();
    parse_str(file_get_contents("php://input"), $b);

1 votes

Cela m'a beaucoup aidé.

1voto

torillt Points 16

Pour référence future : Sur une boîte Ubuntu, je suis confronté à ce problème depuis relativement longtemps et j'avais l'habitude d'adopter une solution de contournement similaire à celle décrite ci-dessus pour sauver la journée. J'ai maintenant retrouvé la trace du problème dans mon php.ini et l'ai finalement trouvé dans la ligne suivante Niveau d'imbrication max_input = 0 J'ai commenté la ligne ci-dessus, redémarré apache et tout est réglé.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X