140

Some guy called one of my Snipplr submissions "crap" because I used if ($_SERVER['REQUEST_METHOD'] == 'POST') instead of if ($_POST)

Checking the request method seems more correct to me because that's what I really want to do. Is there some operational difference between the two or is this just a code clarity issue?

Scott
  • 6,411
  • 6
  • 39
  • 43
  • @vinkoVrsalovic especially since as mentions in his answer they are not the same and ($POST) is a sort of "hack" in that your check if an array, that only is present during a POST request, exists. Also the request method can be used in other cases like GET. – Hawken May 12 '12 at 16:42
  • 13
    You should use `===` instead of `==` here as `0 == 'POST'`. – dave1010 Feb 22 '13 at 12:11
  • 5
    $_SERVER["REQUEST_METHOD"] may contain "POST" for HTTP GET requests on some PHP+Apache2 installations. Like mine. And this is how I got here. – oxygen Aug 13 '13 at 19:26
  • 3
    @Tiberiu-IonuțStan If that's true (which I don't believe it is), it's a grossly serious bug. Can you provide a link to a PHP or Apache bug report? Steps to reproduce? As it is, I just don't believe you. – Mark Amery Mar 23 '14 at 12:25
  • 1
    @dave1010 Why would `$_SERVER['REQUEST_METHOD']` ever be the number `0`? As far as I know, that's impossible. – Mark Amery Mar 23 '14 at 12:27
  • @MarkAmery It's a matter of faith. Really. – oxygen Mar 23 '14 at 13:49
  • Hmm first time I've ever come across this. Last team I worked on used `if ( $_POST )` all over the place (though they were known to do lots of things incorrectly). I'm glad you asked this. I'm just 10 years late, hah. – Phil Tune Nov 21 '18 at 14:21
  • I find it convenient to just place a value in a variable along with my post or just use the submit value. And whether it is or not is up for debate I suppose, but it FEELS safer, I've never found a need to do otherwise. – RationalRabbit May 14 '21 at 14:39

11 Answers11

180

Well, they don't do the same thing, really.

$_SERVER['REQUEST_METHOD'] contains the request method (surprise).

$_POST contains any post data.

It's possible for a POST request to contain no POST data.

I check the request method — I actually never thought about testing the $_POST array. I check the required post fields, though. So an empty post request would give the user a lot of error messages - which makes sense to me.

Amal Murali
  • 75,622
  • 18
  • 128
  • 150
gnud
  • 77,584
  • 5
  • 64
  • 78
  • Theoretically, it could be possible, that the request method is 'post' (lower- or even mixed case). Does PHP automatically sanitize this on GET and POST? – Boldewyn Mar 22 '10 at 13:24
  • After a short test, my PHP 5.2 on WinXP obviously doesn't do it, so probably the request_method should be sanitized to uppercase only. – Boldewyn Mar 22 '10 at 15:42
  • 3
    @Boldewyn No, it doesn't, but if the client sends you a request method of 'post' or 'Post' when they intend to perform a POST request then they're in violation of spec, since HTTP methods are case-sensitive according to spec and the spec only defines the POST method, not e.g. the post or Post or pOsT method. I go into more detail about this in my answer here: http://stackoverflow.com/a/21511879/1709587. Whether or not you want to coerce the method to uppercase to handle spec-violating client code is your choice. – Mark Amery Mar 23 '14 at 12:32
  • And since they're not the same thing, it makes sense that we might use them for different things -- type and request payload. I wonder if this makes anyone barf: I use $_SERVER['REQUEST_METHOD'] to figure out what we're doing, and I use $_REQUEST to access the payload, which maintains a little independence between the concepts (in other words, I rarely use $_POST or $_GET specifically). – grantwparks Aug 08 '14 at 15:35
  • @grantwparks That sounds like bad deal. $_GET and $_POST have more to do with where the data was transported. Consider: "curl -k -L -X POST -H 'Content-Type: text/csv' --data-binary \@sample.csv 'test-script.php?test=12345'" The value "test" populates $_GET even though the method is POST. – txyoji Jun 01 '16 at 20:30
46

if ($_SERVER['REQUEST_METHOD'] == 'POST') is the correct way, you can send a post request without any post data.

Tamil Selvan C
  • 19,913
  • 12
  • 49
  • 70
stuartloxton
  • 2,006
  • 3
  • 14
  • 11
21

I used to check $_POST until I got into a trouble with larger POST data and uploaded files. There are configuration directives post_max_size and upload_max_filesize - if any of them is exceeded, $_POST array is not populated.

So the "safe way" is to check $_SERVER['REQUEST_METHOD']. You still have to use isset() on every $_POST variable though, and it does not matter, whether you check or don't check $_SERVER['REQUEST_METHOD'].

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
binaryLV
  • 9,002
  • 2
  • 40
  • 42
15

If your application needs to react on request of type post, use this:

if(strtoupper($_SERVER['REQUEST_METHOD']) === 'POST') { // if form submitted with post method
    // validate request, 
    // manage post request differently, 
    // log or don't log request,
    // redirect to avoid resubmition on F5 etc
}

If your application needs to react on any data received through post request, use this:

if(!empty($_POST)) {  // if received any post data
   // process $_POST values, 
   // save data to DB,
   // ... 
}

if(!empty($_FILES)) { // if received any "post" files
   // validate uploaded FILES
   // move to uploaded dir
   // ...
}

It is implementation specific, but you a going to use both, + $_FILES superglobal.

DUzun
  • 1,693
  • 17
  • 15
4

You can submit a form by hitting the enter key (i.e. without clicking the submit button) in most browsers but this does not necessarily send submit as a variable - so it is possible to submit an empty form i.e. $_POST will be empty but the form will still have generated a http post request to the php page. In this case if ($_SERVER['REQUEST_METHOD'] == 'POST') is better.

sra
  • 23,820
  • 7
  • 55
  • 89
Eamon
  • 41
  • 1
  • 2
    In that case, `$_POST` would not be empty: it would be an array with empty values. – TRiG Dec 23 '10 at 13:36
4

They are both correct. Personally I prefer your approach better for its verbosity but it's really down to personal preference.

Off hand, running if($_POST) would not throw an error - the $_POST array exists regardless if the request was sent with POST headers. An empty array is cast to false in a boolean check.

Rakesh kumar Oad
  • 1,332
  • 1
  • 15
  • 24
Eran Galperin
  • 86,251
  • 24
  • 115
  • 132
2

As long as I may need to access my PHP scripts with more than one method, what I do actually is:

if (in_array($_SERVER['REQUEST_METHOD'],array("GET","POST","DELETE"))) {
// do wathever I do 
}
1
$this->method = $_SERVER['REQUEST_METHOD'];
if ($this->method == 'POST' && array_key_exists('HTTP_X_HTTP_METHOD', $_SERVER)) {
    if ($_SERVER['HTTP_X_HTTP_METHOD'] == 'DELETE') {
        $this->method = 'DELETE';
    } else if ($_SERVER['HTTP_X_HTTP_METHOD'] == 'PUT') {
        $this->method = 'PUT';
    } else {
        throw new Exception("Unexpected Header");
    }
}
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • 5
    Although your answer might be correct, it is not helpful without explanation! Please have a look at [answer]! Thank you! – jkalden Feb 27 '17 at 13:33
-1

It checks whether the page has been called through POST (as opposed to GET, HEAD, etc). When you type a URL in the menu bar, the page is called through GET. However, when you submit a form with method="post" the action page is called with POST.

-3

It's really a 6 of one, a half-dozen of the other situation.

The only possible argument against your approach is $_SERVER['REQUEST_METHOD'] == 'POST' may not be populated on certain web-servers/configuration, whereas the $_POST array will always exist in PHP4/PHP5 (and if it doesn't exist, you have bigger problems (-:)

Alana Storm
  • 164,128
  • 91
  • 395
  • 599
-18

They both work the same way, but $_POST should be used as it is cleaner. You can add isset() to it to check it exists.

Alex UK
  • 57
  • 2
  • 6
    `$_POST` will always exist, though it may be empty (which is cast to boolean `false`). And what do you mean by "cleaner"? – TRiG Dec 23 '10 at 13:37
  • 2
    maybe he meant that less characters are needed to type on the keyboard =P – Julian Oct 09 '15 at 07:24