Organizational Research By

Surprising Reserch Topic

php post array empty upon form submission

php post array empty upon form submission  using -'php,arrays,forms,post'

I have a custom CMS i've built that works perfectly on my dev box (Ubuntu/PHP5+/MySQL5+).

I just moved it up to the production box for my client and now all form submissions are showing up as empty $_POST arrays.

I found a trick to verify the data is actually being passed using file_get_contents('php://input'); and the data is showing up fine there -- the $_POST/$_REQUEST arrays are always empty.

I've also verified the content-type headers are correct as well via firebug (application/x-www-form-urlencoded; charset=utf-8).

This issue is happening regardless of whether a form is submitting via AJAX or a regular form submit.

Any help is greatly appreciated!

asked Sep 24, 2015 by r3tt
0 votes

Related Hot Questions

17 Answers

0 votes

Here's another possible cause -- my form was submitting to without the WWW. and I had set up an automatic redirect to add the "WWW." The $_POST array was getting emptied in the process. So to fix it all I had to do was submit to

answered Sep 24, 2015 by devkumargupta
0 votes

Make sure that, in php.ini:

  • track_vars (it's only available on very old PHP versions) is set to On
  • variables_order contains the letter P
  • post_max_size is set to a reasonable value (e.g. 8 MB)
  • (if using suhosin patch) and suhosin.request.max_vars are large enough.

I suppose the second suggestion of mine will solve your problem.

answered Sep 24, 2015 by ajit.chavhan
0 votes

I know this question was about POST via a Form, but came here looking for answers for similar issue when POSTing with JSON content-type. Found the answer and wanted to share it as it cost me much time.

When using JSON content-type the $_POST array will not populate (only with multi-part forms I believe)

Here is what did work to correct the issue:

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

hope this helps someone!

answered Sep 24, 2015 by kotmus2002
0 votes

I had a similar problem. Turned out to be a simple fix. In the form I had

where directory was the name of... the directory. My POST array was totally empty. When I looked at the url in my browser, it was displayed with a forward slash on the end.

Adding the forward slash to the end of my action did the trick -

My $_POST array was full again!

answered Sep 24, 2015 by sachin wagh
0 votes

I could solve the problem using enctype="application/x-www-form-urlencoded" as the default is "text/plain". When you check in $DATA the seperator is a space for "text/plain" and a special character for the "urlencoded".

Kind regards Frank

answered Sep 24, 2015 by dahiyabecomp
0 votes

Don't have an elegant solution at this point but wanted to share my findings for the future reference of others who encounter this problem. The source of the problem was 2 overriden php values in an .htaccess file. I had simply added these 2 values to increase the filesize limit for file uploads from the default 8MB to something larger -- I observed that simply having these 2 values in the htaccess file at all, whether larger or smaller than the default, caused the issue.

php_value post_max_size xxMB
php_value upload_max_filesize xxMB

I added additional variables to hopefully raise the limits for all the vars but these didn't have any effect with this problem unfortunately.

In summary, I can't really explain the "why" here, but have identified the root cause. My feeling is that this is ultimately a suhosin/htaccess issue, but unfortunately one that I wasn't able to resolve other than to remove the 2 php overridden values above.

Hope this helps someone in the future as I killed a handful of hours figuring this out. Thanks to all who took the time to help me with this (MrMage, Andrew)

answered Sep 24, 2015 by rajeshujade
0 votes


POST method

We are going to make some modifications so POST method will be used when sending the request...

var url = "get_data.php";
var params = "lorem=ipsum&name=binny";"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) {

Some http headers must be set along with any POST request. So we set them in these lines...

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

With the above lines we are basically saying that the data send is in the format of a form submission. We also give the length of the parameters we are sending.

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

We set a handler for the 'ready state' change event. This is the same handler we used for the GET method. You can use the http.responseText here - insert into a div using innerHTML(AHAH), eval it(JSON) or anything else.


Finally, we send the parameters with the request. The given url is loaded only after this line is called. In the GET method, the parameter will be a null value. But in the POST method, the data to be send will be send as the argument of the send function. The params variable was declared in the second line as lorem=ipsum&name=binny - so we send two parameters - 'lorem' and 'name' with the values 'ipsum' and 'binny' respectively.

answered Sep 24, 2015 by sameer rathore
0 votes

I've found that when posting from HTTP to HTTPS, the $_POST comes empty. This happened while testing the form, but took me a while until I realize that.

answered Sep 24, 2015 by manju bhargava
0 votes

In my case it was because I was using jQuery to disable all inputs on the page just before using jQuery to submit the form. So I changed my "disable every input even the 'hidden' types":


to "disable only the 'button' type inputs":


This was so the user couldn't accidentally hit the 'go' button twice and hose up our DB! It seems that if you put the 'disabled' attribute on a 'hidden' type form input their values won't be sent over if the form is submitted!

answered Sep 24, 2015 by ashish singh
0 votes

For me, .htaccess was redirecting when mod_rewrite wasn't installed. Install mod_rewite and all is fine.


  ErrorDocument 404 /index.php

was executing.

answered Sep 24, 2015 by vijaygupta1980
0 votes

I know it's been a while since this post, but I thought I would contribute what the problem was for me.

I was getting the following error from 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"]

Once I removed my mod security configuration to test, it all worked as expected. Now I just need to modify my rules to stay secure but flexible enough for my needs :)


answered Sep 24, 2015 by 20shahi
0 votes

In addition to MRMage's post:

I had to set this variable to solve the problem that some $_POST variables (with an large array > 1000 items) disappeared:

suhosin.request.max_vars = 2500

"request", not "post" was the solution...

answered Sep 24, 2015 by girisha
0 votes

This is sort of similar to what @icesar said.

But I was trying to post stuff to my api, located in site/api/index.php, only posting to site/api since it gets passed on to index.php by itself. This however, apparently cause something to get messed up, as my $_POST got emptied on the fly. Simply posting to site/api/index.php directly instead solved it.

answered Sep 24, 2015 by deepak
0 votes

Not the most convenient solution perhaps, but I figured it out that if I set the form action attribute to the root domain, index.php can be accessed and gets the posted variables. However if I set a rewritten URL as action, it does not work.

answered Sep 24, 2015 by thiru
0 votes

I came across a similar yet slightly different issue and it took 2 days to understand the issue.

  • In my case also POST array was empty.

  • Then checked with file_get_contents('php://input'); and that was also empty.

Later I found that browser wasnt asking confirmation for resubmitting form data after If I refresh the page loaded after POST submission. It was directly refreshing page. But when I changed form URL to a different one it was passing POST properly and asked for resubmitting data when attempted to refresh page.

Then I checked what is wrong with actual URL . There were no fault with URL, however it was pointing to a folder without index.php in URL and I was checking POST at index.php.

Here I doubted the redirection from / to /index.php causes POST data to be lost and tested URL with appending index.php to the URL.

That Worked.

Posted it here so someone would find it helpful.

answered Sep 24, 2015 by sumit_jaiswalmca
0 votes

My problem was that I was using the HTML tag to change the base URL of my test site. Once I removed that tag from the header, the $_POST data came back.

answered Sep 24, 2015 by okesh.badhiye
0 votes

Are you sure you understand server and client side languages? The fact that you are saying that whether or not a form is submitted via AJAX means you may not. How are you using $_POST and AJAX?

Try creating a new so-test.php file with the following content and putting it on your server:

',print_r($_POST, TRUE),'

'; } ?>

Once that file is up, post a URL for further help.

answered Sep 24, 2015 by sameer rathore