php $_POST array empty upon form submission
Asked Answered
C

32

120

I have a custom Content Management System (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!

Concern answered 15/8, 2009 at 21:35 Comment(2)
Check post_max_size: the value must be set as 8M, not 8MB. In the latest case, you won't see any errors, but $_POST size will set to 0Stretchy
Beware: Apache does a 301 redirect if slash is missing.Chefoo
V
244

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

Here is how I correct the issue:

$_POST = json_decode(file_get_contents("php://input"), true);
Vaish answered 10/2, 2013 at 4:58 Comment(3)
Another alternative is to change Content-Type header to application/x-www-form-urlencoded and then serialize your data with $.param(dataObject). That should help.Edwardoedwards
@ŁukaszBachman How to do that if dataobject is something like........title=something&body=anything. I want to get the vale of title & body. $dataobject["title"] returns empty. In my case $_POST is empty. And the only way to get it using file_get_contents("php://input")...except that it is not json encoded.Windom
toptal.com/php/…Geyer
V
104

Here's another possible cause:

My form was submitting to domain.example 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 www.domain.example

Vacate answered 27/10, 2009 at 16:22 Comment(4)
Dammit, a url rewrite in my htaccess was the cause of POSTs not working. I was automatically appending slash to all url's, but in the code as the ACTION I was using a url without a slash. Your answer helped, as I never thought to check the .htaccess. +1Terylene
I had domain forwarding (with masking) using Godaddy, and this seems to be the source of the problem.Thanks!Romanticize
I also had a similar problem, it was coming from my .htaccess file. It was stripping the .php extension from the URL, and my form was POSTing to the URL with the extension.Sewage
I stumbled upon this answer after hours spent on debugging of my WordPress endpoint. Thanks a lot!!Harlot
C
30

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

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

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 -

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

My $_POST array was full again!

Cavite answered 20/11, 2012 at 20:29 Comment(2)
This shouldn't be a fix, for example on CakePHP, that has a good routing system, failed on this, (I don't mean Cake failed), maybe the approach to this problem is not the framework or the .php files, but some config on apache, I'd like to do further investigation upon this problem. It's quite interesting.Brewer
On a similar note, I had the same issue as the OP, but only if the <form> tag didn't have a name attribute, and only in IE.Badmouth
Q
16

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) suhosin.post.max_vars and suhosin.request.max_vars are large enough.

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

Quarrelsome answered 15/8, 2009 at 21:45 Comment(2)
Thanks MrMage, appreciate your insight and will check those ini settings out and let you know if that did the trick. Thanks!Concern
"post_max_size" setting is my showstopper. I was uploading a large file during form submit, and this setting contained a less value. So i am getting an empty post array when i submit the form.Landgrabber
R
11

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.

Redeeming answered 9/8, 2012 at 14:50 Comment(0)
F
6

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.

Frink answered 23/4, 2014 at 12:40 Comment(2)
I had the same problem, without '/'at the end of url, nothing exists in $_REQUEST , but with '/' or '/index.php' , all posted data exists in $_REQUEST. It might be my nginx settings or some thing else!Crouse
Adding forward slash at the end of my fetch URL fixed it for me too, for instance: fetch("https://myurl.com/api/") instead of just fetch("https://myurl.com/api")Pebrook
S
6

If you are posting to a index.php file in a directory for example /api/index.php make sure in your form you specify the full directory to the file e.g

This

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

OR

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

works.

But this fails

<form method="post" action="/api"> 
</form>
Stephanystephen answered 27/7, 2016 at 14:48 Comment(3)
I actually have the exact opposite. I discovered that /my_uri would work but not /my_uri/.Decal
had the same problem. it seems that apache or nginx adds a redirect from /api to /api/Roof
Apache does an automatic redirect 301 if slash is missing. Thanks for your answer and comments are useful too.Chefoo
U
5

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

Unparalleled answered 30/12, 2010 at 19:8 Comment(0)
B
5

Having the enable_post_data_reading setting disabled will cause this. According to the documentation:

enable_post_data_reading

Disabling this option causes $_POST and $_FILES not to be populated. The only way to read postdata will then be through the php://input stream wrapper. This can be useful to proxy requests or to process the POST data in a memory efficient fashion.

Bandore answered 13/5, 2016 at 19:45 Comment(0)
T
5
<form action="test.php" method="post">
                        ^^^^^^^^^^^^^

Okay, this was stupid and I will be embarassing myself in public, but I knocked up a little test script for something in PHP and when my $_POST array was empty, StackOverflow is the first place I looked and I didn't find the answer I needed.

I had only written

<form action="test.php">

and forgotten to specify the method as being POST!

I am sure someone will snigger, but if this helps someone else who does the same thing, then I don't mind! We all do it from time to time!

Thunderstruck answered 8/12, 2016 at 11:5 Comment(1)
can't belive i forgot that also! I'm just trying a new server, and tought that was something due the configuration ... anyways, thanks for the reminder!Sanctitude
C
4

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 suhosin.post.xxx/suhosin.upload.xxx 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)

Concern answered 16/8, 2009 at 18:9 Comment(2)
It might be worth asking this question over on Serverfault, particularly if the issue lies in the server set-up/htaccess.Bottle
If i am not mistaken, the size should be specified like 'xxM', and not 'xxMB', so i wonder if that might have something to do with it...Stiles
E
4

In my case, when posting from HTTP to HTTPS, the $_POST comes empty. The problem was, that the form had an action like this //example.com When I fixed the URL to https://example.com, the problem disappeared.

Exurbia answered 27/6, 2019 at 17:14 Comment(2)
I think is something related on how the server is setup. I am having the same issues using GoDaddy as a host. This solution didn't solve the issue.Interurban
This solution solved my issue. I had a nice headeach.Regazzi
M
3

same issue here!

i was trying to connect to my local server code via post request in postman, and this problem wasted my time alot!

for anyone who uses local project (e.g. postman): use your IPv4 address (type ipconfig in cmd) instead of the "localhost" keyword. in my case:

before:

localhost/app/login

after:

192.168.1.101/app/login
Meritocracy answered 11/1, 2019 at 8:22 Comment(1)
Postman has given me a few issues with scraped json values that have quotation marks or spaces. It expects a specific format.Clinkscales
E
3

Make sure that the name property of each field is defined.

This create you an empty POST on PHP

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

But, this will work

<input type="text" name="Phone" id="Phone">
Embolism answered 7/10, 2019 at 22:17 Comment(2)
I think is something related on how the server is setup. I am having the same issues using GoDaddy as a host. This solution didn't solve the issue.Interurban
For those who care, you might have to go into the nightmare of setting your own .htaccess.Interurban
J
3

I had the same problem. The problem was .htaccess.

I have a HTTPS rewrite rule and was sending the post requests to http:// instead of https://. The post request cleared due to redirect.

Judd answered 16/12, 2020 at 17:30 Comment(0)
W
2

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

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

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) {
    alert(http.responseText);
  }
}

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.

http.send(params);

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.

Weatherproof answered 12/6, 2010 at 18:9 Comment(0)
B
2

I know this is old, but wanted to share my solution.

In my case the issue was in my .htaccess as I added variables to raise my PHP's max upload limit. My code was like this:

php_value post_max_size 50MB
php_value upload_max_filesize 50MB

Later I notice that the values should like xxM not xxMB and when I changed it to:

php_value post_max_size 50M
php_value upload_max_filesize 50M

now my $_POST returned the data as normal before. Hope this helps someone in the future.

Barrington answered 7/2, 2019 at 20:22 Comment(0)
N
1

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

Specifically:

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

was executing.

Nibelungenlied answered 25/8, 2011 at 2:49 Comment(0)
H
1

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

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

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

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

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!

Hatchway answered 14/9, 2011 at 8:14 Comment(0)
V
1

I just spent hours to fix a similar issue. The problem in my case, was the the

max_input_vars = "1000"

by default, in the php.ini. I had a really huge form without uploads. php.ini is set to upload_max_filesize = "100M" and post_max_size = "108M" and it was surely not the issue in my case. PHP behavior is the same for max_input_vars when it exceeds 1000 variables in the form. It returns and empty _POST array. I wish I could have found that one hours, and hours ago.

Vasti answered 22/8, 2018 at 1:53 Comment(0)
R
1

Another simple reason for an empty POST array can be caused by not closing a form with </form> and then adding a second <form>...</form>. When the second form is submitted the POST array will be empty.

Razid answered 4/1, 2021 at 18:57 Comment(0)
N
0

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

Nussbaum answered 7/6, 2011 at 19:50 Comment(0)
F
0

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

Fatty answered 1/5, 2012 at 13:44 Comment(0)
P
0

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.

Pseudohermaphrodite answered 22/5, 2013 at 6:20 Comment(0)
O
0

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.

Olivares answered 16/1, 2014 at 20:9 Comment(0)
H
0

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

Hogfish answered 5/4, 2015 at 3:2 Comment(0)
C
0

In my case (php page on OVH mutualisé server) enctype="text/plain" does not work ($_POST and corresponding $_REQUEST is empty), the other examples below work. `

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

`

More here: method="post" enctype="text/plain" are not compatible?

Callimachus answered 3/10, 2015 at 16:30 Comment(0)
T
0

Make sure you use name="your_variable_name" in input tag.

I mistakenly use id="your_variable_name".

I spent much time to catch the bug.

Tumult answered 11/12, 2018 at 2:42 Comment(0)
C
0

I run into the same issue also when I migrated to new server. setting the value for post_max_size in the php.ini file fixed my issue.

Caddoan answered 14/9, 2021 at 8:43 Comment(0)
C
0

In my case, I had target="_blank" in my <form> tag. Removing it solved the issue.

But, if you need to open a new page after submission nonetheless, just replace _blank with a random value, like newtab (it can really be anything).

Before:

<form target="_blank" action="api/" enctype="application/x-www-form-urlencoded" method="post">

After:

<form target="newtab" action="api/" enctype="application/x-www-form-urlencoded" method="post">
Clink answered 2/11, 2022 at 18:48 Comment(0)
S
0

mkdir tmp

chmod 777 tmp

In may case I'm using virutalbox and tried to increase all suggested variables. But they not solved my issue, I created a tmp direcotry in the project and the issue resolved. You need to find that where your project looking for tmp directory and verify if it is exist.

Strongminded answered 5/7, 2023 at 13:36 Comment(0)
P
-1

OK, I thought that I should put my case here .... I was getting the post array empty in specific cases .. The form works well, but some times users complain that they hit submit button, and nothing happens ..... After digging for a while, I discovered that my hosting company has a security module that checks users inputs and clears the whole post array (not only the malicious data) if it discovers so. In my example, a math teacher was trying to enter the equation: dy + dx + 0 = 0; and data was wiped completely.

To fix this, I just advise him now to enter the data in the text area as dy + dx + 0 = zero, and now it works .... This can save someone some time ..

Parch answered 6/1, 2018 at 16:58 Comment(2)
Asking users to make allowances for faulty code is a non-starter.Guillory
It's not really faulty code but you might consider a new hosting provider. Alternatively post the input in a different form, e.g. HTML URL encoding.Clinkscales

© 2022 - 2024 — McMap. All rights reserved.