PHP - same trivial code behaving differently in two places
June 11, 2006 12:48 PM   Subscribe

Short piece of PHP code - all it does is set a variable and POST it back to the same PHP code - that works when executed on my hosted web site, but doesn't work when executed on my local machine running XAMPP.

All I'm doing is setting a variable, and POSTing it to the same piece of PHP code, so that the first time the code executes (no variable set yet) one thing happens, and the second time the code executes (variable has now been set and POSTed) something different happens.

My web host is running PHP 4 on Apache on Linux, and locally I'm running PHP 5 on Apache on Windows (via XAMPP.)

I'd like to know how to fix the code so it works in both locations, if possible.

On my desktop all it does is keep going to Case (0) where the variable $answer has not been set. On my web host it progresses through the three cases each time you click the button, so after the second click it hits the place where it echoes DONE and finishes.

Warning: I'm self-taught - the whole thing may be a bad way of doing things. I'm willing to accept an alternate solution, but I'd still like to know why this doesn't work in both environments:



Test of Post





Testing Post


< ?php # if ($answer=1) { $switchflag=1; } if ($answer> 1) {
$switchflag = 2;
}
if (!isset($answer)) {
$switchflag = 0;
}

switch ($switchflag) {
case (0):
# Case where answer =0 never been through yet
echo "

First time through, because no value for answer has been passed.

";
echo "";
echo "";
echo "";
break;
}

switch ($switchflag) {
case (1):
echo "

Second time through because answer has been passed with a value of 1.";
echo "";
echo "";
echo "";
break;
}

switch ($switchflag) {
case (2):
# Last time through
echo "


DONE";
break;
}
?>

posted by lockedroomguy to Computers & Internet (22 answers total)
 
Whoops, code didn't post properly. Working on fixing asap.

Sorry to waste your time.
posted by lockedroomguy at 12:51 PM on June 11, 2006


I can't figure out how to post the code so it shows up.

All I want to do is have a button. When the user clicks it, it sets a variable and calls the same piece of code again. But this time, it POSTS the variable like this:

action=\"testpost.php?answer=1\" method=\"post\">";

At the beginning of the code I have a series of Switch and Case statements to test the value of $answer and then execute the appropriate piece of code based on that.

You can see it actually working here:

http://www.mysteryscenemag.com/phptest/testpost.php

The exact same code just repeats the first page over and over on my local machine.
posted by lockedroomguy at 12:56 PM on June 11, 2006


register_globals is off locally and on on the server, likely. use $_POST[myvar] to access POSTed variables
posted by devilsbrigade at 1:13 PM on June 11, 2006


actually, if all you're sending is answer=1 on the URL line, you should be using GET, and you should be using $_GET
posted by devilsbrigade at 1:14 PM on June 11, 2006


And, just because I don't read the qusetion all the way through, I'd probably use a session variable instead of a URL flag (or use both). YMMV. Its an alright way of doing it.
posted by devilsbrigade at 1:15 PM on June 11, 2006


devilsbrigade has it. See this and this for more info.
posted by cerbous at 1:21 PM on June 11, 2006


Thanks - it looks like I've got my answer from devil's brigade! But it will take me a while to understand these and understand exactly what I have to do - I'll mark best answers later tonight.

Anyone know of a nice layman's explanation of the difference between GET, POST, $_GET, and session variables anywhere?
posted by lockedroomguy at 1:30 PM on June 11, 2006


Layman's explanation of GET/POST:

GET = variables contained in a link, like www.example.com?aaa=1&bbb=2
POST = variables from a form submitted with the submit button with method=post

For most purposes that's all you need to know.
posted by reklaw at 1:44 PM on June 11, 2006


Using $_GET and $_POST is preferred to relying on register_globals. So you should definitely switch to using those. Specifically, replace all occurences of $answer with $_GET['answer'].

By the way, you made a typo/error on the very first line. '=' is assignment and '==' is comparison. Change that to

if ($_GET['answer']==1).
posted by Khalad at 2:00 PM on June 11, 2006


You do need to have a good understanding of HTTP variables before you can effectively program a web application.

When you submit a form, the form fields end up as POST variables. When you get a URL that looks like "?foo=bar", foo ends up as a GET variable.

Now, PHP gets these, but doesn't automatically make them available as PHP variables that you can perform program logic upon. If the PHP configuration setting register_globals is on, PHP will make them available automatically. This is a major security risk. register_globals should not be on. In this, more common case, the variables are still available to PHP, but only in the special arrays _GET and _POST. This forces you to THINK about where the data is coming from when you write your program, which is a good thing.

Your form is confusing the idea of GET and POST variables. When you change the URL of the form's ACTION attribute, you're making a GET variable. If you were to actually change the form fields, you'd be changing the POST variables.

I know you're just learning now. But it's important to know what's going on behind the scenes, otherwise when you go to write a real program, you *will* screw it up for lack of that knowledge.
posted by jellicle at 2:19 PM on June 11, 2006


Whoa.

So even if I say Method="post" then I can be doing a GET?

This seems to reflect another problem I've never understood. If GET is supposed to show the variable value in the url, and POST doesn't, then why does the variable value show in my urls which use POST.

I'm guessing jellicle's answer is skinning up against my misconception. There's POST, and then there are POST variables, and there's GET, and then there are GET variables? You can use GET and make a POST variable, and use POST and make a GET variable? I had thought that if you used Method=post then you got a POST variable, end of story. Where can I look to understand this better?

This is why I was asking if there was a good novice description somewhere. I've looked at the PHP manual online, including all the added comments, and I've got a PHP manual, but I am still having a problem with what-the-heck GET, POST, Get variables, POST variables, _GET, session variables, etc are. and when to use which.

Book, course, or online references welcome.

Thanks to all responders so far. You've helped.
posted by lockedroomguy at 4:43 PM on June 11, 2006


When you submit a form, the form fields end up as POST variables.

... unless your form's action is set to "get"!

Your form is confusing the idea of GET and POST variables.


No it's not, it's just using both, which as far as I know is perfectly legal.
posted by AmbroseChapel at 4:44 PM on June 11, 2006


The key difference between get and post is that post should be used for anything which changes something on the server.

If you're seaching google, it uses get, because it's literally getting something from google's database: it asks a question of the database and you get your answer back.

If you're buying something online, on the other hand, that should use post, because it's deducting something from your bank account and adding something to their database of "stuff to send out to customers". There are before and after states, and in the "after" state, you're down $50 and they're up $50.

So that's why, if you reload a page created by a post, the browser should give you an "are you sure you want to do this?" error message.
posted by AmbroseChapel at 4:50 PM on June 11, 2006


I had thought that if you used Method=post then you got a POST variable, end of story.

That's right. But your form uses both, if it's got its action set to "scriptname.php?foo=bar" that's a hard-coded GET, and if the method is set to POST for the rest of the form then you're using both. I'm not sure why it's coded that way but obviously it works. Perhaps it's just to make the form simpler and avoid having one more hidden field.
posted by AmbroseChapel at 4:54 PM on June 11, 2006


AmbroseChapel - it is using both, which is perfectly legal, but I do think the poster is confusing them.

<form name="input" action="testpost.php?answer=1" method="post">
<input name="submit" type="submit" value="GoFirst">
</form>

When the above form is submitted, you end with a GET variable of "answer", equal to "1", and a POST variable of "submit", equal to "GoFirst". The GET variable exists because the ACTION URL includes a question mark followed by the string answer, an equals sign, and a 1. The POST variable exists because the input field in the form is named submit and has a value of GoFirst.

If and only if register_globals is set, these are available in PHP as "$answer" and "$submit".

Whether or not register_globals is set, they are available in PHP as "$_GET['answer']" and "$_POST['submit']".

Try including this in all your test forms for a while:

echo "<br>GET variables:<br>";
var_dump($_GET);
echo "<br>POST variables:<br>";
var_dump($_POST);

Hopefully that will clear things up for you.
posted by jellicle at 5:05 PM on June 11, 2006


One more post?

The thing that's making it work differently on the server and your computer is a security thing.

The server is less secure than your computer, because they changed the defaults a while back for that register_globals thing.

Slightly silly example, but pretend you've got a GET form for me to buy something from an online store.

Your form sends your server this:

buy.php?item=t-shirt&price=$10

and your script does this:

looks up my credit card details;
puts the number into $credit_card_number;
gets the details from the form and charges my card the $10;


if register_globals is switched on, I could hack the form by hand like this:

buy.php?item=t-shirt&price=$10&credit_card_number=1234567890

and my hand-crafted credit card number would over-write yours from the database.

What they've done is put all fields derived from forms in a little locked box, so my hacked variable would end up in $_GET['credit_card_number'] and not clobber yours from the database.
posted by AmbroseChapel at 5:09 PM on June 11, 2006


Khalad, thanks for pointing out the error. I didn't actually make that error - it's correct in the code, but for some reason an = got dropped in the posting. (I just couldn't let everyone here think I got EVERYTHING wrong.)
posted by lockedroomguy at 5:11 PM on June 11, 2006


Thanks all, it's all helping.

Thanks for the clarification Jellicle. I think you're right about me mixing up GET and POST. I thought that the Method=post was applying to the Action= on the same line, but you're saying one can be GET, even if I don't have a Method of GET. I really did not (and do not) understand that.

I'll read up on the suggested links from cerbous, and AmbroseChapel's examples, and I'll insert the variable dump suggested by Jellice until I do understand it.

Thanks all.
posted by lockedroomguy at 5:32 PM on June 11, 2006


Unrelated to the GET/POST confusion, you don't need to use three switch statements. One will do. Furthermore, you don't need $switchflag, $answer can be used. Your code really boils down to this:
if ( !isset($_GET['answer']) ) $answer = 0;
else $answer = $_GET['answer'];

switch($answer)
{
  case 0:
         // do stuff
         break;
  case 1:
        //do stuff
        break;
  case 2:
        //do stuff
        break;
  default:
       // catch anything that isn't the first three, 
      //  probably do nothing
}

posted by ddf at 6:27 PM on June 11, 2006


AmbroseChapel, your example of the security problem is actually wrong. Its only an issue if it isn't initialized somewhere in the code. register_globals won't overwrite variables you initialize yourself... the danger is something like (in pseudocode, its been a long time since I've used php)

if($cc_number != null)
-- use_cc_number();
else
-- $cc_number = get_cc_from_db();

if you just do
$cc_number = get_cc_from_db();
$cc_number will be overwritten no matter what (unless PHP has exceptions now), and you're 'safe.'
posted by devilsbrigade at 7:57 PM on June 11, 2006


If you say so. I didn't actually test it, as you can probably tell.

It seems lockedroomguy is still a little confused though:

I thought that the Method=post was applying to the Action= on the same line


It is. That's exactly what your form does. If it was just

<form action="script.php" method="post">

it would send only post values. If it was just

<form action="script.php" method="get">

it would send only get values. But it's an unusual type of form, because it's

<form action="script.php?foo=bar" method=post">

and so it combines both.
posted by AmbroseChapel at 8:07 PM on June 11, 2006


It may be enlightening to see what's going on under the covers, at the HTTP-protocol level. Or it might be even more confusing, but let's try it and see!

When you visit a URL, or submit a form, your browser sends an HTTP request to the web server, which looks like this:

    POST1 /script.php2?foo=bar3

    baz=quux&answer=24


1 - The request method. Almost always GET or POST. If POST, then after this line you have a blank line followed by the POST variables, which in PHP end up in $_POST. If the method is GET you can refresh the page at will; if it's POST, your browser will pop up an "Are you sure you want to resubmit your data?" confirmation box.

2 - The request URL. Obvious.

3 - The query string (optional). This is where the $_GET array comes from. You can have a query string with both a GET and POST request; in the latter case, $_GET will be filled out with the variables from the query string even though the request method is POST.

4 - The POST data. This data is only sent for POST requests (duh).

...

How does this relate to your web page? Well, the method attribute on your <form> element controls 1, the request method. The action attribute sets 2, the request URL, and optionally 3, the query string.

If the method is "get" then
your form data will be tacked onto the query string and will be available in the $_GET array in your PHP script. If it's "post" then your form data will be sent in 4, the POST data.

In either case, anything you manually put in the query string will be available in $_GET.

Tip: If you want to see what data ended up where, use var_dump. You can see all the GET and POST data by typing:

var_dump($_GET); var_dump($_POST);
posted by Khalad at 9:24 PM on June 11, 2006


« Older What does 'Terror' mean?   |   Legitimate Work From Home Newer »
This thread is closed to new comments.