Tutorial: GPC variables the good way!
GPC variables are in the basics of PHP, yet many programmers don't use them correctly. I though it might be useful to post a tutorial on this.
First, a definition, GPC stands for Get-Post-Cookie, the three main locations from where variables may comes from the outside of the script.
I see many programmers who use the registered globals to grab GPC data. like $page to access the page variable that was passed through the url. It works fine, but many server disable the register_globals option in the configuration because it increase the execution for nothing (php have to generate all these globals, this takes time) and can lead to security leaks (some scripts can be 'hacked' simply by passing some variable through the url). And with newer PHP versions, the register_globals option is DISABLED by default (and i hope it gets deprecated and always off in the future
)
PHP have some great superglobal variables to access GPC data, $_GET, $_POST and $_COOKIE (there are others, but they're not in the scope of this tutorial)
superglobal means it can be accessed everywhere, no need to use the global keyword to access them in functions.
these arrays are way better in my opinion. You know where this variable comes from, no need to include them in the current scope with 'global'. It just makes your script more portable and easier for other to understand.
let's say I write this:
if( isset( $id ) )
{
// some code
}
Do you know where $id comes from? was it defined earlier in the script, does it comes from the url? a form? a cookie?
now if I write this:
if( isset( $_POST['id'] ) )
{
// some code
}
now it is clearer isn't it?
and in the first one, you could add ?id=abc to the url to hack this script and the condition would be true and that code executed. You do not want this do you?
Since any variable that comes from the outside of the script can be changed by the user, it is VERY important to double check it before using it.
first we want to check if the variable is set. for this PHP have the nice isset() function. The difference between if( $_GET['foo'] ) and
if( isset( $_GET['foo'] ) ) is that the second one won't generate a notice error if the foo variable wasn't passed through the url.
You should also check the value of the variable to be sure it is what you really expect it is.
let's say you want to grab the id of a record from the url, you would use the following lines:
$id = ( isset( $_GET['id'] ) ) ? intval( $_GET['id'] ) : 0;
if( $id != 0 )
{
// do the query
}
else
{
// do nothing
}
now you know that the id is set and it is an integer. if you dont check it with intval(), someone could set it to a string (say a part of a query) that might screw up the code
the same applies to anything that comes through GPC, be it the path of a file (where you want to check if that file exists and is in the webroot, i was once able to view some files, like the php.ini one, on someone's server only by using filename=../../../../Windows/php.ini in the url. you really do not want this to happen)
Now let's talk about backslashes. Have you ever had problems before where ' gets into \\', or " getting into \"?
The solution is simple, stripslashe to every GPC vars at the beginning of the script, and you're clear for the whole script
I use this little snippet I wrote some time ago for this, I got the idea from phpBB2, but I used the recursivity of a function (the ability of a function to call itself) to do the work. I saw later that vB do it the same way
PHP:<?php
function stripslashes_gpc( &$var )
{
while( list( $key, $value ) = each( $var ) )
{
if( is_array( $var[$key] ) )
{
stripslashes_gpc( $var[$key] );
}
else
{
$var[$key] = stripslashes( $value );
}
}
reset( $var );
}
if( count( $_GET ) > 0 )
{
stripslashes_gpc( $_GET );
}
if( count( $_POST ) > 0 )
{
stripslashes_gpc( $_POST );
}
if( count( $_COOKIE ) > 0 )
{
stripslashes_gpc( $_COOKIE );
}
?>
I put this in a file (only this!), and include it only if PHP added slashes to GPC vars with this in my common file:
PHP:<?php
if( get_magic_quotes_gpc() )
{
require 'includes/stripslashes_gpc.lib.php';
}
?>
Now that every GPC vars don't have quotes, you have to put them back if you wish to insert that in a database. But watch out, you only want to add slashes to \ and ' or " (only add slashes to the type of quote that you use for the query string)
I have this function to do the work (i quote ' since I only use that kind of quote, i dont like double quotes):
PHP:<?php
function add_slashes( $text )
{
$text = str_replace( '', '', $text );
$text = str_replace( '', '', $text );
return $text;
}
?>
[EDIT:aa6d47ace4]
Because of that damn badly coded vB i can't post that function because it shows all screwed up.
So, in the first argument of the first str_replace, it's two backslashes (\\), and for the replace it's 4 backslashes (\\\\)
and for the 2nd str_replace, the first argument is a backslash with a single quote (\\') and the replace is 3 backslashes with a single quote (\\\\')
again: damn badly coded vb, had to edit this 4 times...
[/EDIT:aa6d47ace4]
That's about it! Phew 
I hope you liked this tutorial and learned something from it!
If you have questions or comments please post them 
___________________
Jeremie - Used to be the Director of Community Development
Last edited by Jeremie, July 3rd, 2003 03:02 PM (Edited 1 times)


Concise and clear, although I'm still a bit "iffy" with the stripslashes() calls. But that's because I've been an anti-magic-quotes person ever since I learnt about the damn "feature"