PHP Lesson 11 - using user input

Started by Parham, September 08, 2003, 11:24:01 PM

Previous topic - Next topic

Parham

Sorry this one was a little late, I realized this was one of the things I was obligated to do, and I'll try to keep them coming in on time.  There are a lot of things I didn't touch base on in this lesson.  If any one of the developers want to add their comments, by all means go ahead.  This particular topic is very hard to write about because there are so many "what ifs" involved.

So let's go back to last lesson's code example:


<html>

<head>

<title></title>

</head>
<body>

<form action="http://www.website.com/script.php" method="post">
Form 1: <input type="text" name="form1"><BR>
Form 2: <input type="text" name="form2"><BR>

<input type="submit" value="submit">
</form>

</body>
</html>


Let's now pretend I submitted that form with information via the "post" method filling in "form1" with "hi" and "form2" with "bye".  To see this visually, I'll show you how it would look via the "get" method:

http://www.website.com/script.php?forms1=hi&forms2=bye

Remember that the only differences between the "post" and "get" methods are:
-"post" doesn't cache information, while "get" does
-the "get" method is limited in the amount of information you can send while the "post" method is not

So how do you access the information you submitted via HTML in the script (script.php)?  Well amazingly, there are several ways to get the information.  It's up to you to decide which method best suites you, and then go with that.  When you submit a form to a script, a certain set of variables are automatically created for you.

The first way to access the information is via the "superglobals" PHP provides.  "Superglobals" are variables that can be accessed anywhere in the script regardless of scope (we'll learn about this later when we get to functions).  The "superglobals" are 9 special associated arrays which hold ALL the information you input into a script.  Here they are:

$_SERVER - these are variables set by the server

$_GET - this is information you send via the "get" method into your script

$_POST - this is information you send via the "post" method into your script

$_COOKIE - this arrays holds all cookie information your computer sends to the script

$_FILES - when you upload files in PHP, they are held inside this array

$_ENV - the environmental variables

$_REQUEST - a combination of all user-input to your script

$_SESSION - much like cookies, these are session variables which hold information for you

I will be concentrating almost all the examples on the "post" and "get" methods because they are the easiest to follow.  There are equivalent older versions of the above which are not "superglobals" and only exist in the global scope (again we'll get into this when we discuss functions).  Here are the "superglobals" and their old deprecated counterparts (remember again that these are associated arrays):

$_SERVER - $HTTP_SERVER_VARS
$_GET - $HTTP_GET_VARS
$_POST - $HTTP_POST_VARS
$_COOKIE - $HTTP_COOKIE_VARS
$_FILES - $HTTP_POST_FILES
$_ENV - $HTTP_ENV_VARS
$_REQUEST - new, didn't exist before
$_SESSION - $HTTP_SESSION_VARS

By now you should be totally confused, and I completely understand if you are, because I haven't explained a thing about how to use these arrays.  Let's take out "get" method example:

http://www.website.com/script.php?forms1=hi&forms2=bye

Here is how I would access the "form1" and "form2" information is submitted inside the script:


<?
echo $_GET['form1'] . "\n"; //prints "hi"
echo $_GET['form2'] . "\n"; //prints "bye"
?>


We submitted our information via the "get" method, therefore the information will populate the $_GET array.  Now if we submitted our information via the "post" method, then we could access they by replacing $_GET with $_POST.  The information we submitted can also be found inside the $_REQUEST array, but it's recommended you don't use this array unless you don't know how your information is coming in (security reasons, nothing to concern yourselves with).

Let's try another basic example:

http://www.website.com/script.php?name1=Jeff&name2=Joseph (remember, this means you either typed this directly inside your address bar in your browser, or that you submitted forms with names "name1" and "name2" via HTML with the "get" method).


<?
echo $_GET['name1'] . ' and ' . $_GET['name2'] . ' are too cool';
//will print "Jeff and Joseph are too cool"
?>


Again, if I submitted my information from a form via the "post" method, I'd simply replace $_GET with $_POST.  Like I said, there are several ways to access information you send into your script.  The "superglobals" are what you should be using all the time.  The deprecated $HTTP_* variables you shouldn't be using anymore.  There are also the global variables which I will explain now:

First to be able to use global variables, you have to have "register_globals" enabled in your php.ini file (if you don't but want it, ask your system admin to enable it).  What these variables allow you to do is use short form versions of your input.  So for example, if I submit a form via the "post" or "get" method called "form1", then I can use the $form1 variable to get its value.  So for another example, if I submit a form named "something" via "post" or "get", and I want to retrieve its value in my script, I could use the $something variable to get it.

With these variables, there's always the question of "what about when I have several different sources of input, all with the same name?".  For example, what if you set a cookie on the user's machine named "variable" and there is a session named "variable" and there is information coming into the form via the "post" method called "variable".  Well then you would have $_COOKIE['variable'], $_SESSION['variable'], and $_POST['variable'] all set.  But what about the $_REQUEST superglobal and the regular globals from (register_globals)?

Well in cases where information is coming in from multiple places with the same name, PHP allows you to set precedence on what is most important.  In your php.ini file, there is a variable called "variables_order" under the "data handling" header.  By default this is what it looks like:


; This directive describes the order in which PHP registers GET, POST, Cookie,
; Environment and Built-in variables (G, P, C, E & S respectively, often
; referred to as EGPCS or GPC).  Registration is done from left to right, newer
; values override older values.
variables_order = "EGPCS"


The explanation on that is good enough.  That means that with $_COOKIE['variable'], $_SESSION['variable'], and $_POST['variable'] all set, $variable will have the value of the cookie variable in it.  Ask questions if you have any :).

Michele

#1
Quote from: Parham on September 08, 2003, 11:24:01 PM
First to be able to use global variables, you have to have "register_globals" enabled in your php.ini file (if you don't but want it, ask your system admin to enable it).  What these variables allow you to do is use short form versions of your input.  So for example, if I submit a form via the "post" or "get" method called "form1", then I can use the $form1 variable to get its value.  So for another example, if I submit a form named "something" via "post" or "get", and I want to retrieve its value in my script, I could use the $something variable to get it.

I wish most hosts would set register_globals to OFF.

Using $form1 instead of $_POST['form1'] is a very real security risk. Since GET usually has precedence over POST, someone could stuff the URL with a javascript or other nasty, and your php code would execute it instead of reading what you sent in the POST variable. Always, always, always validate the data coming in. If it's supposed to be an integer, verify it's an integer, if it shouldn't be an url, make sure http:// isn't in the variable, escape html_entities when needed.

And using $_REQUEST is just as bad as using $form1, since $_REQUEST also doesn't care if the info came via GET, POST, COOKIE or whatever.

I think that info should be in your tutorial so new coders don't get used to using $form1... ever! :)

Per the php.ini file:

- register_globals = Off         [Security, Performance]
;     Global variables are no longer registered for input data (POST, GET, cookies,
;     environment and other server variables).  Instead of using $foo, you must use
;     you can use $_REQUEST["foo"] (includes any variable that arrives through the
;     request, namely, POST, GET and cookie variables), or use one of the specific
;     $_GET["foo"], $_POST["foo"], $_COOKIE["foo"] or $_FILES["foo"], depending
;     on where the input originates.  Also, you can look at the
;     import_request_variables() function.
;     Note that register_globals is going to be deprecated (i.e., turned off by
;     default) in the next version of PHP, because it often leads to security bugs.
;     Read http://php.net/manual/en/security.registerglobals.php for further
;     information.
Dubito ergo cogito ergo sum

Seph|roth

question: my server has register_globals turned on, can i manually turn it off, or do i have to ask my host to do that?

Parham

I've never tried it myself, but apparantly you can put this line in your .htaccess file to disable register_globals:

Quote
php_flag register_globals off

this apparantly works too:

Quote
php_value register_globals 0

but it doesn't matter whether it's on or off, the key point is that you shouldn't rely on them.  You should strictly rely on the superglobals now.  I myself don't practice what i preach, because I use the global variables (it's a very bad habit).  But I use them and CHECK them a lot for variable poisoning.

[Unknown]

*cough*

And, just so you know SMF uses the super globals not the ugly globals ;).

-[Unknown]

Seph|roth

#5
Quote from: Parham on September 09, 2003, 01:41:50 PM
I've never tried it myself, but apparantly you can put this line in your .htaccess file to disable register_globals:

Quote
php_flag register_globals off

this apparantly works too:

Quote
php_value register_globals 0

but it doesn't matter whether it's on or off, the key point is that you shouldn't rely on them.  You should strictly rely on the superglobals now.  I myself don't practice what i preach, because I use the global variables (it's a very bad habit).  But I use them and CHECK them a lot for variable poisoning.
well, my site uses ?p=somepage for navigation, and i use switch ($p) to get the var.. so to be safe i should use $_GET['p'] ? is that correct? Thanks!

EDIT: i just realise that i use CASE to determine what page to show, so if something wrong or malicious is entered in the address field after ?p=  then the default CASE is applied. So in this case, it isn't a security risk if i understand right?

[Unknown]

No, but it's still best to use the superglobals because we all hope one day register_globals will no longer be an option.  (okay, I know it's just me.)

-[Unknown]

Parham

I actually hope it's taken out... because then i can just extract() from whichever superglobals I want

Nemesis

QuoteThe explanation on that is good enough.  That means that with $_COOKIE['variable'], $_SESSION['variable'], and $_POST['variable'] all set, $variable will have the value of the cookie variable in it.  Ask questions if you have any

If the order goes EGPCS (Environment, Get, Post, Cookies, and Session), then wouldn't $variable hold what _SESSION['variable'] set it to?
MY BLOG    
WISHLIST    
DONATE

[Unknown]

I thought it was EGPCS = ENV, GET, POST, COOKIE, SERVER....?

-[Unknown]

Nemesis

MY BLOG    
WISHLIST    
DONATE

[Unknown]

Quote from: Nemesis on October 30, 2003, 07:04:18 PMI am a dummy sometimes.

Aren't we all?  I certainly am - and quite often too...

Still, I think it's sad (:P - sorry Parham :P.) if someone can't type a few more letters to use a superglobal...

-[Unknown]

Parham

Quote from: [Unknown] on October 30, 2003, 07:25:50 PM
Quote from: Nemesis on October 30, 2003, 07:04:18 PMI am a dummy sometimes.

Aren't we all?  I certainly am - and quite often too...

Still, I think it's sad (:P - sorry Parham :P.) if someone can't type a few more letters to use a superglobal...

-[Unknown]

the only (only one) reason i don't like superglobals is because you can't use them inside double quotes.  even that's not a reason NOT to use them.  EVERYONE should use superglobals :D.

[Unknown]

"Why can't $_REQUEST[you]?"

-[Unknown]

Parham

under some circumstances, it breaks.  i never knew this initially so when i first started using PHP, i converted one of my old scripts (and of course used superglobals).  But like half of my print lines spit out errors, and when i showed them to Zef, he told me that with superglobals, it's BEST to concatinate them into strings and not to put them directly in because PHP will sometimes spit out errors.

[Unknown]

Mostly it's when you do two arrays... like:

"$this[wont][work]"

Instead you should do:

"{$this['will']['work']}"

But of course I don't see why you should use double quotes ANYWAY so... :P.

-[Unknown]

Parham

Quote from: [Unknown] on October 31, 2003, 08:35:25 AM
Mostly it's when you do two arrays... like:

"$this[wont][work]"

Instead you should do:

"{$this['will']['work']}"

But of course I don't see why you should use double quotes ANYWAY so... :P.

-[Unknown]

Why do you hate my Unknown? :P LOL
Yes yes your right, of course your right.  All I mean to say is that if they worked inside double quotes, more people would be inclined to use them.  I still use double quotes, it's my lazy-factor :P

Ardenn

I hope people are still reading and responding to this thread.  I need a little help.  I have been following the lessons here without too much difficulty up to this point.

For the purposes of my example I will be using the practice code from the lesson of IF statements.

Here is my HTML form:
<form action="action.php" method="POST">
What Color is the box?: <input type="text" color="color" /><br/>
<input type="submit">
</form>


I am using the POST method to get the data to action.php.  Action.php is the code from the "IF" statement lesson slightly modified:

<?

$ball = $_POST["color"]; //try changing it to "yellow", "blue", "green", "purple", or any other color
if ($ball == "red") { //if this expression returns true, run the block
  $redbox = $ball;
} elseif ($ball == "yellow") { //if this statement returns true, run the block
  $yellowbox = $ball;
} elseif ($ball == "blue") { //ditto
  $bluebox = $ball;
} elseif ($ball == "green") { //ditto
  $greenbox = $ball;
} elseif ($ball == "purple") { //ditto
  $purplebox = $ball;
} else { //run this if none of the following were run
  $colorlessbox = $ball;
}
echo "red box: $redbox<br>";
echo "yellow box: $yellowbox<br>";
echo "blue box: $bluebox<br>";
echo "green box: $greenbox<br>";
echo "purple box: $purplebox<br>";
echo "colorless box: $colorlessbox<br>";

?>


Now if I understand this code correctly, if I enter the color yellow into my form and press submit, I should get this output:

Quotered box:
yellow box: yellow
blue box:
green box:
purple box:
colorless box:

But I am not getting that output.  Instead Im getting this output:

Quotered box:
yellow box:
blue box:
green box:
purple box:
colorless box:

Can someone tell me what Im doing wrong?
Ardenn // Traxxus
http://www.twinwand.com
D&D Play by Post Community Looking for Players and DM's

[Unknown]

Heh... it's always the little typos.  I should know, I'm a blinking magnet for them.

It's this:
<input type="text" color="color" />

Notice anything wrong there?  There's no "color" attribute ;). (should be name.)

-[Unknown]

Ardenn

#19
still didnt work

I changed my HTML to:

<form action="action.php" method="get">
What Color is the box?: <input type="text" name="color" /><br/>
<input type="submit">
</form>


No changes to the PHP script are required.

Ardenn // Traxxus
http://www.twinwand.com
D&D Play by Post Community Looking for Players and DM's

[Unknown]

Try using print_r.  In other words, do:

print_r($_POST);

That way, you can see what is being submitted, if anything.

-[Unknown]

Ardenn

I fixxed it.. It was another silly typo..  Thank you so much for your help.  I've only been studying this for a day and Im pretty amazed about how easy it is.  Its just that I have to keep using it to really learn it.


Ardenn // Traxxus
http://www.twinwand.com
D&D Play by Post Community Looking for Players and DM's

pulpitfire

was the error that you need to put a spacer between the variable and the <br> tag?

e.g.

echo "red box: $yellowbox ' . <br>";

because otherwise, it might interpret the <br> tag as part of your variable $yellowbox, and come up with nothing?

[Unknown]

Quote from: Ardenn on December 04, 2003, 02:47:15 PM
I fixxed it.. It was another silly typo..  Thank you so much for your help.  I've only been studying this for a day and Im pretty amazed about how easy it is.  Its just that I have to keep using it to really learn it.




Ahh, don't sweat.  I'm considered a pro here.... (I think they say it just so I'll keep working on SMF :P.) and I make just as many, if not more typos.  So you're already (according to those who say I'm a pro...) part way there!

Yeah... takes work like everything else, but.. at least in my opinion, it's fun.  Then again, I also actually like Caclulus, Networking, Physics, Web Design, Economics, and several other VERY nerdy things.  And I think they are fun too.

Maybe that's why I don't have a girlfriend... run while you still can!

-[Unknown]

Ardenn

The error was a left over for something I did to -TRY- to fix the thing in the first place.

I keep 2 sets of files.  Those that are reference and those that I play with.  The reference are direct copies of the code from here  in the "IF" lesson and also in the HTML form.

I just happen to double check on my "play" files that the form was GET and the PHP script was POST.  So Stupid mistake 1 resolved.

The next thing is that I changed the variable name in the HTML to name="name" just like I had seen it on another example, and left the PHP script at $_POST["color"].  Stupid mistake number 2 resolved.

I did indeed make the mistake color="color" and once all three were resolved it worked like a charm.  It was just alot of "lil" mistakes.
Ardenn // Traxxus
http://www.twinwand.com
D&D Play by Post Community Looking for Players and DM's

[Unknown]

Quote from: pege on December 04, 2003, 03:00:06 PM
was the error that you need to put a spacer between the variable and the <br> tag?

e.g.

echo "red box: $yellowbox ' . <br>";

because otherwise, it might interpret the <br> tag as part of your variable $yellowbox, and come up with nothing?

That's why I recommend you don't go through the headache and problems, and rather just do this:

echo 'red box: ', $yellowbox, '<br />';

  - most languages don't have interpolation, so it's a bad habit to get into.
  - interpolation is not only slow, but often confusing - especially with arrays.
  - I always prefer to use xhtml (<br />) rather than html since it is backwards compatible. (<br>)

-[Unknown]

Bartrainer

I installed php as a module. My question is: Which php.ini file is the one that is used to determine the behaviors of php? I have one in the modules folder in apache, and i have one in the php folder.

These tutorials are great, i'm glad i found them.
Everyone that says "it can't be done" is followed by someone that just did it.  The possibilities are as Powerful as your imagination...

"There are No bad cocktails, just bad drinkers."

[Unknown]

If you have a phpinfo, it will tell you where it's looking for php.ini.

-[Unknown]

Bartrainer

Awesome, it's looking for it in Apache2, does that mean i should delete all the other php.ini files?

Thanks.
Everyone that says "it can't be done" is followed by someone that just did it.  The possibilities are as Powerful as your imagination...

"There are No bad cocktails, just bad drinkers."

[Unknown]

Probably the "safest" idea.  But it shouldn't be a problem.

-[Unknown]

Grek.Kamchatka

How to forbid repeated pressing the button "submit"? In base one value, after the first pressing should be brought only, the field is cleared and by pressing the button "submit" the script should not work.! isset does not approach.

[Unknown]

You have to use JavaScript to prevent them from hitting submit multiple times, usually.

-[Unknown]

Grek.Kamchatka

Thanks, I tried, but it has not turned out. Have you an example of a script?

Advertisement: