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 action='form.php'>
<input type='text' name='email'>
<input type='submit' value='Submit your email'>

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 is used for data passed using the HTTP GET method, which includes variables passed as part of the URL (such as 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:

// For demonstration only, there are security concerns with doing things this way
echo $_GET['$email']; 
//will display whatever was entered in the form (form.html)
echo $_GET['var1']; 
//will display 'xx' when the script is called from the URL 
echo $_GET['var2']; 
//will display yy from the URL above.
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).


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:

<form method='POST' action='postform.php'>
<input type='text' name='email'>
<input type='submit' value='Submit your email'>

print $_POST['email'];

$_POST has been around since PHP 4.1.0. Before that, $HTTP_POST_VARS was used (though this was not automatically global).


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.


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


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).


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).


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:

It's easy to see what the results would be in your own environment. Create a simple script to loop through and display all elements of the array.

// server.php
foreach ($_SERVER as $key=>$value)
   echo "$key $value<br>" ;

Calling this script with a couple of parameters, i.e., 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_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)
PATH /bin:/usr/bin:/usr/local/bin
SCRIPT_FILENAME /var/www/phpbuilder/server.php
Apache/1.3.33 Server at 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
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).


This varies according to the PHP environment. In my environment, the displaying the entire array by calling the script env.php, below:

// env.php
foreach ($_ENV as $key=>$value)
   echo "$key $value<br>" ;


PATH /bin:/usr/bin:/usr/local/bin


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).


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!