5.7. Sessions
A PHP session allows an application to store information for the current "session," which can be defined as one user being logged in to your application. A session is identified by a unique session ID. PHP creates a session ID that is an MD5 hash of the remote IP address, the current time, and some extra randomness represented in a hexadecimal string. This session ID can be passed in a cookie or added to all URLs to navigate your application. For security reasons, it's better to force the user to have cookies enabled than to pass the session ID on the URL (which normally can be done manually by adding ?PHP_SESSID=<session_id>, or by turning on session.use_trans_sid in php.ini) where it might end up in web server's logs as a HTTP_REFERER or be found by some evil person monitoring your traffic. That evil person can still see the session cookie data, of course, so you might want to use an SSL-enabled server to be really safe. But, to continue discussing sessions, we're going to rewrite the previous cookie example using sessions. We create a file called session.inc that sets some session values, as shown in the following example, and include this file at the beginning of any script that is part of the session:
<?php
ini_set('session.use_cookies', 1);
ini_set('session.use_only_cookies', 1);
session_start();
?>
On the first line, the configuration parameter 'session.use_cookies' is set to 1, which means that cookies will be used for propagation of the session ID. On the second line, 'session.use_only_cookies' is set to 1, which means that a session ID passed in the URL to the script will be discarded. The second setting requires that users have cookies enabled to use sessions. If you cannot rely on people having cookies enabled, you can either remove this line, or you can change the value to 0, which ensures that there is no global setting for this configuration parameter in php.ini or another place.
Tip
You can configure the place where PHP will store session files with the session.save_path configuration setting.
The session_start() function must come after any session-related settings are done with ini_set(). Session_start() initializes the session module, setting some headers (such as the session ID cookie and some caching-prevention headers), requiring its placement before any output has been sent to the browser. If no session ID is available at the time, session_start() is called, a new session ID is created, and the session is initialized with an empty $_SESSION array. Adding elements to the $_SESSION array is easy, as shown in the following example. This modified version of our login page shows the changed lines in bold:
<?php
include 'session.inc';
function check_auth() { return 4; }
?>
<html>
<head><title>Login</title></head>
<body>
<?php
if (isset ($_POST['login']) && ($_POST['login'] == 'Log in') &&
($uid = check_auth($_POST['email'], $_POST['password'])))
{
/* User successfully logged in, setting cookie */
$_SESSION['uid'] = $uid;
header('Location: http://kossu/session/index.php');
} else {
?>
/* HTML form comes here */
<?php
}
?>
</body>
</html>
Tip
You can call session_name('NAME') before calling session_start() in your script to change the default PHP_SESSID name of the session ID cookie.
We first include our session.inc file. Adding the session variable 'uid' to the session is done easily by setting the uid element of the $_SESSION superglobal to the value of $uid. Unsetting a session variable can be done with unset($_SESSION['uid']).
Tip
If you need to process a lot of data after modifying your session variables, you might want to call session_write_close(), which is normally done automatically at the end of the script. This writes the session file to disk and unlocks the file from the operating system so that other scripts may use the session file. (You will notice that pages in a frame set might load serially if they use frames because the session file is locked by PHP.)
Tip
The locking described here will not always work on NFS, so scripts in a frame set might still get the old non-updated session data. Avoid using NFS to store session files.
Logging out is the same as destroying the session and its associated data, as we see in the logout script:
<?php
session_start();
$_SESSION = array();
session_destroy();
header('Location: http://kossu/session/login.php');
?>
We still need to initialize the session with session_start(), after which we can clear the session by setting the $_SESSION superglobal to an empty array. Then, we destroy the session and its associated data by calling session_destroy().
Session variables are accessed from the $_SESSION superglobal. Each element contains a session variable, using the session-variable name as key. In our index.php script, we moved the if statement that checks whether a user is logged in to a special function that we place in the session.inc file:
function check_login() {
if (!isset ($_SESSION['uid']) || !$_SESSION['uid']) {
/* If no UID is in the cookie, we redirect to the login page */
header('Location: http://kossu/session/login.php');
}
}
In this function, we check whether the 'uid' session variable exists and whether the value of the 'uid' session variable is not 0. If one of the checks fail, we redirect users to the login page; otherwise, we do nothing and let the calling script handle it from there. We call the check_login() function on every page where we require a user to be logged in. We need to make sure the session.inc file is included before any output is produced because it may need to send headers to the browser. Here is a snippet from the modified index.php script:
<?php
include 'session.inc';
check_login();
?>
<html>
<!-- rest of HTML follows here -->
Using sessions can be as simple as what's shown here. Or, you can tweak some more parameters. Check out the php.ini-dist file that accompanies the PHP distributions.
|