![]() Join Up! 96816 members and counting! |
|
|||
Fundamentals of PHP Superglobals
Ian Gilfillan
This month's article is aimed at PHP developers who're not yet familiar with the PHP superglobals. Usage of superglobals is fundamental to PHP web development, but, with all the recent changes in PHP, there are still many outdated tutorials, books, and sadly, still much confusion.
PHP superglobals are automatically available throughout all scripts, in all scopes. In other words, you don't have to do anything, no declaring, no passing - they're just there. They provide useful information about the environment, allow access to HTML form variables or parameters, access to cookies stored on a client, as well as keeping track of sessions and file uploads.
Accessing HTML form variables in PHP
The beginner might still come across an online tutorial or book that has something like the following:
form.html <form action='form.php'> <input type='text' name='email'> <input type='submit' value='Submit your email'> </form> form.php <?php print $email; ?>
I strongly suggest reading last month's article, Secure Programming with PHP, in conjunction with this, as that covers some important security issues, and I don't want to be accused of encouraging bad habits. But for now, let's just take these examples at face value, for descriptive purposes. In the above example, $email is a global, and is populated from the form. However, this behaviour causes security issues, and comes from a setting called register_globals. Old versions of PHP had this setting on by default, but newer versions don't, and it's bad practice. $email will not be populated in most PHP installations these days, a cause of much newbie frustration.
So what to do? Simple - PHP creates what are called superglobals that are populated from different places. There are a number that can be used for form data. There's $_GET, $_POST, $_REQUEST and $_GLOBALS. There're also the older variables $HTTP_GET_VARS and $HTTP_POST_VARS. Don't use these any more - they still work, but are deprecated, and don't behave in quite the same way.
$_GET
$_GET is used for data passed using the HTTP GET method, which includes variables passed as part of the URL (such as www.example.co.za/index.php?var1=xx&var2=yy) or from an HTML form that does not define any method (as in the case of form.html above). Here's how a PHP script would access them:
Simple isn't it? The GET method is conventionally used when the processing script has no lasting observable effect on matters (such as changing a database). It's also more easily cacheable, so is ideal most searched.
$_GET has been around since PHP 4.1.0. Before that, $HTTP_GET_VARS was used (though this was not automatically global).
$_POST
The HTTP POST method is very similar, and is conventionally used when the contents of the form are going to change something. But the mechanics are the same, except they use the $_POST superglobal, for example:
$_POST has been around since PHP 4.1.0. Before that, $HTTP_POST_VARS was used (though this was not automatically global).
$_REQUEST
It's preferable to use the specific superglobal that is intended to contain the variables. If you know a variable is being passed using the GET method, use $_GET. If you know it's being POSTED, use $_POST. But there are times when you may not be sure. I recently came across a script that received the same variable from both the GET and POST methods, depending on how it was called. There's an easy option in this case - use $_REQUEST. It contains all variables passed from both methods, as well as those contained in $_COOKIE (discussed below). In any of the examples above, you could replace $_POST or $_GET with $REQUEST, and the result would be identical.
$_REQUEST has also been around since PHP 4.1.0. Before version 4.3.0, in addition to the contents of $_POST, $_GET and $_COOKIE, $_REQUEST also contained $_FILES (discussed below) information.
$_GLOBALS
The final superglobal that can be used for forms is $_GLOBALS. It's really a super superglobal, as it contains references to all variables in the script's global scope. Replacing $_POST or $_GET with $_GLOBALS in the examples above would also have the identical results. $_GLOBALS has been around since PHP 3.0.0
$_COOKIE
Contains all variables passed from HTTP cookies. $_COOKIE has been around since PHP 4.1.0. Before that, $HTTP_COOKIE_VARS was used (though this was not automatically global).
$_SESSION
This superglobal keeps all session variables. See the article Maintaining State with PHP4 Sessions for more info, or the documentation on PHP sessions.
$_SESSION, as with most of the superglobals, has been around since PHP 4.1.0. Before that, $HTTP_SESSION_VARS was used (though this was not automatically global). $_SERVER
This superglobal contains information passed from the web server. Web servers differ, so all of the following may not be available under your setup. If you're running PHP from the command line, most of these become pretty meaningless. Here's a list of elements in the array:
Calling this script with a couple of parameters, i.e. http://phpbuilder.co.za/server.php?var1=2&var2=3, produces the following output:
DOCUMENT_ROOT /var/www/phpbuilder
HTTP_ACCEPT text/xml,application/xml,application/xhtml+xml, text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5 HTTP_ACCEPT_CHARSET ISO-8859-1,utf-8;q=0.7,*;q=0.7 HTTP_ACCEPT_ENCODING gzip,deflate HTTP_ACCEPT_LANGUAGE en-us,en;q=0.5 HTTP_CONNECTION keep-alive HTTP_COOKIE MANTIS_PROJECT_COOKIE=8; MANTIS_VIEW_ALL_COOKIE=3 HTTP_HOST phpbuilder.co.za HTTP_USER_AGENT Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.6) Gecko/20050317 Firefox/1.0.6 HTTP_VIA 1.1 cbs-cache1 (NetCache NetApp/5.6.2D16) HTTP_X_FORWARDED_FOR 165.146.136.106 PATH /bin:/usr/bin:/usr/local/bin REMOTE_ADDR 198.54.202.18 REMOTE_PORT 23171 SCRIPT_FILENAME /var/www/phpbuilder/server.php SERVER_ADDR 216.32.75.242 SERVER_ADMIN webmaster@phpbuilder.co.za SERVER_NAME phpbuilder.co.za SERVER_PORT 80 SERVER_SIGNATURE Apache/1.3.33 Server at phpbuilder.co.za Port 80 SERVER_SOFTWARE Apache/1.3.33 (Debian GNU/Linux) PHP/4.3.10-13 mod_ssl/2.8.22 OpenSSL/0.9.7d GATEWAY_INTERFACE CGI/1.1 SERVER_PROTOCOL HTTP/1.1 REQUEST_METHOD GET QUERY_STRING var1=2&var2=3 REQUEST_URI /server.php?var1=2&var2=3 SCRIPT_NAME /server.php PATH_TRANSLATED /var/www/phpbuilder/server.php PHP_SELF /server.php argv Array argc 1
$_SERVER has also been around since PHP 4.1.0. Before that, $HTTP_SERVER_VARS was used (though this was not automatically global).
$_ENV
This varies according to the PHP environment. In my environment, the displaying the entire array by calling the script env.php, below:
produces
LANG C PATH /bin:/usr/bin:/usr/local/bin $_FILES
When uploading files with an HTTP POST, these elements are populated to provide feedback to the script.
$_FILES has also been around since PHP 4.1.0. Before that, $HTTP_POST_FILES was used (though this was not automatically global).
Conclusion
The PHP superglobals are likely to remain unchanged for a while. After all the recent changes, and resultant confusion for new developers, now's a good time to get it right and learn how to use them properly. Good luck!
|