PHP some $ _POST values ​​are missing, but present in php: // input

I have a very large html form (containing a table with rows containing several inputs) that I need to send to a PHP script through a POST request. The problem is that some values ​​do not pass and are absent in PHP $ _POST superglobal.

I checked (using the Firebug extension) that the values ​​are actually sent to the server by the browser.

$ _ POST is populated, but some values ​​are simply missing.

I checked what is a raw request using:

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

and the returned string matters. They simply are not parsed into the $ _POST array. The strange thing I noticed is that the input php: // values ​​are truncated after some length, and the rest of the line does not go into $ _POST.

I thought about post_max_size and memory_limit and set them to large values:

 memory_limit = 256M post_max_size = 150M 
but according to php documentation $ _POST should not contain any values ​​if request made is bigger than post_max_size.

Due to the large size of the form and the request, I cannot post it here, but I can send a php script, I used to debug the problem:

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

Server Version: Apache / 2.2.9 (Debian)
PHP version: PHP 5.3.2-0.dotdeb.2

Can I explain the reason for such strange behavior of PHP, and what should I do (change php settings, code?) To use the $ _POST array when processing the form?

EDIT: to be clear: not only the values ​​are missing. $ _POST also does not contain these keys.

ex fragment of the original message:

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

The key "t_dodparam" is in the column and has the key 198. The remaining parameters are absent (ex t_dodparam2 is in the message, but it does not have such a key as 198, and there is no such key as n_wartosc in $ _POST)

+48
post php
Feb 22 '11 at 12:14
source share
11 answers

PHP modifies fields containing space characters, periods, open brackets, and others compatible with obsolete register_globals

you can find many workarounds in the comments here: php: variables from external sources

For example (POSTER comment):

 <?php //Function to fix up PHP 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; } ?> 
+29
Feb 22 '11 at 13:00
source share

I just fixed this problem by adding a value to max_input_vars in my PHP configuration file. In accordance with this . it was introduced in 5.3.9, but after some package updates I ran into a problem in 5.3.2.

The default value for max_input_vars is 1000, which is too small for my form.

+30
Mar 12 2018-12-12T00:
source share

There are many different things that can be the cause of this. It is best to check the error log. Many of the things that cause this symptom put messages in the error log, but do not display errors in your PHP application.

Some of the possible reasons are:

Suhosin

Suhosin is an extension for PHP designed to protect servers and users from known and unknown flaws in PHP applications and the PHP core. One of the things he does is limit the size of $ _POST, $ _GET, $ _REQUEST and $ _COOKIE. If your problem is Suhosin, you will get an error message in your log, for example

ALERT - POST variable limit exceeded - reset 'foo' variable

The solution is simple, just increase the maximum number of allowed variables in php.ini. If you do not have a section of Sukhozin, simply create one. For example:

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

There are other Suhosin settings that can cause this, but these are the most likely candidates.

Invalid form field names

In the old days, PHP had a parameter called register_globals (now stripped) that automatically converted the GET and POST variables to PHP variables. Therefore, if your form had the "foo" and "bar" fields, when you submit this form, the variables $ foo and $ bar are automatically created. However, there are several characters that are not allowed for use in PHP variable names (space, dot, open square bracket, and others). Depending on what characters you used, a variable may have invalid characters, deprived of its value, or be canceled. Although register_globals is no longer used, PHP still separates these characters when building $ _POST, $ _GET, $ _REQUEST and $ _COOKIE. If you cannot correct the values ​​of the form fields, you can try something like:

 <?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; } ?> 
+10
Dec 09 '11 at 9:01 a.m.
source share

How about using parse_str to convert a query string to php structures? This function is the inverse of http_build_query.

  $b = array(); parse_str(file_get_contents("php://input"), $b); 
+6
Feb 21 '12 at 15:00
source share

I found this answer through a search and felt that I had to offer an alternative question. In my case, my post was not too large, and yet the value that I submitted in the field did not appear in the $ _POST array. As it turned out, I accidentally had a different field in my form with the same name. So:

 <form> <input type="text" name="field1"> <input type="text" name="field2"> <input type="text" name="field3"> <input type="text" name="field1"> <input type="submit"> </form> 

When the $_POST variable is populated with data from this form, the value in your first field will be overwritten by the value in this last field with the same name. If the first field is required and you fill in the value, but the last field is not required and will be sent blank, you will see similar symptoms like this question, because the value of $ _POST ['field1'] will show the value of the last element in the form that is empty.

TL; DR:

Be sure to check for duplicate field names in your form!

+1
Jan 16 '13 at 16:08
source share

For future reference: In the Ubuntu box, I struggled with this problem for a long time and used a workaround similar to the one described above to save the day. Now I was tracking the problem on my php.ini and finally found it according to max_input_nesting_level = 0 I commented out the line above, restarted apache and fixed it.

+1
Jan 29 '14 at 19:52
source share

I am sending the jQuery.ajax () function. I tried to extract my data from $_POST , but was incomplete. Then I found this post that set me on the right track. However, the getRealPOST () method described above did not work for me - it cannot handle multidimensional and nested arrays very well. Instead, I used the PHP parse_str() method, which did the trick and was a little cleaner:

 $rawdata = file_get_contents('php://input'); $urldecoded = urldecode($rawdata); parse_str($urldecoded, $parsed); $data = $parsed['data']; 

(In my JS, I am sending an object where the payload is in the data property. You will probably be different.)

I also went into my php.ini and worked max_memory and max_input_vars , but it didn't seem to solve my problem. I also spent some time chasing the red herring because I used my error log to print raw data, and I forgot that error_log has a limit on the number of characters it will print if you remember to increase it.

In any case, I hope that this will help anyone who is faced with this problem.

+1
Sep 04 '14 at 23:25
source share

I had the same problem and it turned out that I used AJAX to dynamically change the input field based on other input in the form. The ajax function re-created the input and did not include the input name.

+1
Dec 04 '14 at 19:47
source share

Came to this (admittedly old) post, trying to find a fix for the Javascript Object bug, including the square brackets in their names, and then PHP got confused and acted as if it hadn't even heard of nesting. @Dalin has a good basic answer, but it does not create a nested array and does not convert value types to boolean / number - hence my version ( get_real_post () is also on GitHub).

Despite the name, this should work identically for _GET (i.e. anything that captures php://input ).

 /** * Gets the _POST data with correct handling of nested brackets: * "path[to][data[nested]]=value" * "path" * -> "to" * -> "data[nested]" = value * @return array */ function get_real_post() { function set_nested_value(&$arr, &$keys, &$value) { $key = array_shift($keys); if (count($keys)) { // Got deeper to go if (!array_key_exists($key, $arr)) { // Make sure we can get deeper if we've not hit this key before $arr[$key] = array(); } elseif (!is_array($arr[$key])) { // This should never be relevant for well formed input data throw new Exception("Setting a value and an array with the same key: $key"); } set_nested_value($arr[$key], $keys, $value); } elseif (empty($key)) { // Setting an Array $arr[] = $value; } else { // Setting an Object $arr[$key] = $value; } } $input = array(); $parts = array(); $pairs = explode("&", file_get_contents("php://input")); foreach ($pairs as $pair) { $key_value = explode("=", $pair, 2); preg_match_all("/([a-zA-Z0-9]*)(?:\[([^\[\]]*(?:(?R)[^\[\]]*)*)\])?/", urldecode($key_value[0]), $parts); $keys = array($parts[1][0]); if (!empty($parts[2][0])) { array_pop($parts[2]); // Remove the blank one on the end $keys = array_merge($keys, $parts[2]); } $value = urldecode($key_value[1]); if ($value == "true") { $value = true; } else if ($value == "false") { $value = false; } else if (is_numeric($value)) { if (strpos($value, ".") !== false) { $num = floatval($value); } else { $num = intval($value); } if (strval($num) === $value) { $value = $num; } } set_nested_value($input, $keys, $value); } return $input; } 
+1
Feb 03 '16 at 16:29
source share

I had the same problem and found a very valuable solution without increasing any limitations or sizes in .ini. We know that max_input_vars = 1000 by default, and this is a prefect. Just do one thing to combine the values ​​of the array and try to accurately determine the number of variables below 1000. Each variable name is considered one of them. For example:

 <code> $i = 10; //counts 1 $i = array(1,2,3,4,5); //counts 5 </code> 

You can do it:

 <code> $i = 1_2_3_4_5; // counts 1 </code> 

Hope for understanding.

0
Jun 26 '13 at 13:55 on
source share

Use htmlspecialchars with your $ _POST. For example:

 $day1=htmlspecialchars($_POST["day"]); 

I hope this works.

-four
Mar 27 2018-12-12T00:
source share



All Articles