Besides the obvious, like security issues, character limits in older browsers, etc. Is there any real difference between $_POST and $_GET besides the method in which data is passed?

I have a script that works perfectly with $_POST but completely falls apart when I try to use $_GET. I rarely use $_GET but in this case I need to. I've never had this issue in the past and I've exhausted all my ideas on what to do next to troubleshoot it.

Any ideas?

Recommended Answers

All 11 Replies

Member Avatar for diafol

This is just my opinion - not an 'expert' one:

$_POST is deemed to be more secure, but that isn't strictly true - your validation will determine the security.
A rule of thumb is $_POST for form data passed via method="post", $_GET for getting data out of querystrings (the squiggly bits after the main part of the url), e.g. example.com?id=1&action=delete&confirm=7253Gyhwk2538r5

A third option exists: $_REQUEST, this picks up data from querystrings and "post-method" forms. I don't think that you should use this, although I know a lot of 'experts' who seem to like it.

URLS
Querystrings are easy to mess up, usually from users who are just curious to see what happens if you change something. Robust validation is a must here. Whenever I pass info that may go to disclose info or change the db, I add a 'confirm' parameter. This is usually a mixture of the other parameters plus a 'salt' (a secret string) which is then hashed using md5(). The validation then checks the parameters and confirm hash to see if the query is valid.

FORMS
A well-designed form with good validation should stop most hacks, but forms and http post headers can be faked. There are some methods to block these - Google them. Although client-side validation will block most bad entries, server-side validation is essential.


//EDIT

Almost forgot - you can use either for ajax calls, although your ajax logic will be slightly different. I tend to use post for these (via Prototype library). I remember reading somewhere that get calls tend to retrieve cached info as opposed to new. Don't know if that is true.

//EDIT 2

Does your url have any weird characters that need to be encoded? If you post (hah! no pun intended) your querystring, somebody will cut it down and give you a heads up on the $_GET array.

Understand. I know of a few pages where validation might be a good idea to implement.

Is there any reason data would be parsed differently between methods? Data passed with either method is the same when received, no? Assuming everything is set up correctly (not much you can do to mess that up), what could cause your script to ignore data passed through the URL but work just fine when using $_POST? There must be condition that exists somewhere in the script that is allowing it to react differently to the two methods. Normally I would think that condition would be a scripting error, but it all looks good to me.

Okay, this is the part where I start to feel foolish 8-) Remember when I said this ... "Normally I would think that condition would be a scripting error" ... Well, I won't keep you in suspense. One of my variables is unique to each user and common in all my queries so I changed it over to a SESSION variable. I was so used to seeing it as POST that I didn't notice when I switched everything over to GET. Ooops.

I'm starting to feel like the poster child for rookie mistakes!

Anyhow, GET resolves one of my issues, but now that I'm thinking of it would GET help me avoid "Confirm Form Resubmission" when the back button is used? Figured I would just ask before I dive into changing scripts for testing purposes.

Member Avatar for diafol

You can put the user_id into a hidden input field if you want, but if you're using session variables, it doesn't need to be passed at all - it's just there.

To avoid resubmission, just send the form to a form handler file which contains the validation code. If successful, return to a page (possibly the original page) if it fails, return to the form with a message informing the sender of the error.

You send users from page to page thus:

<?php header("Location: form.php");?>

This works as long as there is no output (html/dtd) to the form handler page before this call. DO NOT use $get to send a form.

It was actually a different variable, but having it set up as $variable=$_GET['variable']; (with no data to 'get') instead of $variable=$_SESSION['variable']; The query failed because of the blank variable.

The problem that I noticed is that when a form is submitted and you are directed to the page containing the results, the results are links themselves that transfer you away from that page. When clicking back to get back to the results page it wants to resubmit the form because there is no data to populate the results when you click back. I just assumed that if I used GET when you click the back button it returns you to the previous URL complete with the info I originally passed and GET would just use that info to repopulate that page. No? It seemed like it would work, haven't tried it yet.

In this case header would not work because the pages in question do output html before the header is called.

Member Avatar for diafol

You could use ajax to populate a results DIV. If you use a library like prototype (prototypejs.org), it reduces the nightmare of setting up ajax objects and return codes.

Your HTML
In the head section:

<script src="scripts/prototype.js" type="text/javascript"></script>
<script src="scripts/myajax.js" type="text/javascript"></script>

In the body section:

<form id="ajaxform">
... controls ...
<input type="button" onclick="doAjaxThing();return false;" value="Send Me!" />
</form> 

<div id="results">
</div>

I use a button here as opposed to a submit button - perhaps semantically wrong but it avoids page refresh. If you need, you can pass parameters within the doAjaxThing().

THE JS in myajax.js

function doAjaxThing(){
   var url = "includes/myupdater.php";
   var myControlValue1 = $F("mycontrol1");
   var myControlValue2 = $F("mycontrol2");
   var myControlValue3 = $F("mycontrol3");
   var params = "mcv1=" + myControlValue1 + "&mcv2=" + myControlValue2 + "&mcv3=" + myControlValue3 
  var oAjax = new Ajax.Updater("results", url,{method: 'post',parameters: params}); 
}

The $F(...) is a shortcut for document.getElementById(...).value. This code passes the values from the form controls ($F) to the url (a php file) via 'post' method. When the php file processes the input, it produces output (via echo or print) and this is returned to the "results" DIV.

The myupdater.php file

<?php
  if(isset($_POST[...])){

     //... get out the parameters ($_POST['mcv1'] to $_POST['mcv3'] in our case) and validate them ... 
    // run your sql code and get the output into a variable, say $output

    echo $output;

  }else{

     echo "<p>No results</p>";
  }
?>

That's all there is to it. You can think of your myupdate.php file like an include file, only used when the form is sent.
Caveat: this is all off the top of my head, no tests, so can't say it will work as is.

LOL ... boy, you have an awful lot going on in the top of your head! I never knew that was even available as an option. Can't say that I know too much about it. I spent the entire day yesterday working with JOINS, thanks for that by the way, I have a decent handle on them now. I suppose it's time to learn something new. I'll take your advice and play around with the ajax thing, seems like a good alternative. Is it really that bad to pass the data with a GET ?

If you want to 'attach' a URL to your submitted data, the use GET. Otherwise use POST.

One example of wanting to have a URL (and therefore using GET) is as follows:
Let's say you have a news site. Each story has a unique ID. There is one PHP script which takes the ID, loads the relevant story from the database, and displays it. To view story 1283 you might visit the URL http://yoursite/viewstory.php?id=1283. Because it has a URL, it means that:
(a) people can bookmark it
(b) hyperlinks can be created for it (either on your site, or on some other site)

An example of where you wouldn't use GET is, say, for a login form.
A person enters their username and password, which is passed to a page called login.php which validates credentials and logs the person in. There is no need to have a special URL for such a page.


So in summary, the rule is: Unless you need to have a URL that incorporates the data, use POST.

I usually use POST almost exclusively with the exception of pagination and a few other instances where it is warranted. I just assumed it may work in this instance as a suitable alternative to avoid page resubmissions when clicking the back button to return to the results page. Take a search engine for example, you wouldn't want to resubmit the form every time you clicked a result to view it and then returned back to the results page. No personal info is being passed, just search criteria ... the same info available to anyone who performs their own search using the same form.

A well-designed form with good validation should stop most hacks, but forms and http post headers can be faked. There are some methods to block these - Google them. Although client-side validation will block most bad entries, server-side validation is essential.

Well actually $_POST is no more secure than $_GET with a htaccess rewrite url system. The reason, anybody can use software like curl to send their on $_POST headers and nower days just about anybody with a little programming experience can do that. So why are there these two systems ($_GET and $_POST), the answer is SEO - Search Engine Optimisation. If you want a search engine to see something then use $_GET or if you don't want a search engine to see something but for everybody else to easily access it then use $_POST. That is the basic concept between those two methods. And as for $_REQUEST - I like to see $_REQUEST as a security flaw feature that has no perpuse. So the flawed $_REQUEST feature in php should be totally ignored as it may have seemed like a good idea to embed into php when it is not.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.