Zend Framework 101: Zend_Session
Implementing "Remember Me" Functionality
A common feature of web sites where users can log in is the ability to be automatically logged-in when the user next visits the web site.
By default, PHP sessions use session cookies, which are cookies that the web browser stores in memory while the browser is running, and destroyed when the browser is exited.
To implement "remember me" functionality, you must change the lifetime of the session cookie so it is not destroyed when the user closes their browser. Zend_Session makes this easy to do.
Additionally, your PHP installation will also periodically delete session cookies after the time specified in the PHP configuration. If this occurs to soon, it doesn't matter whether the user's browser has remember their session ID – the session data will no longer be saved on the server!
Extending the Session Cookie Lifetime
To make the browser session cookie stay alive when users close their browser, use theZend_Session::rememberMe()
static method. This method takes an optional single argument, which is the number of seconds before the cookie will expire. If no value is specified then a default of two weeks is used.
Listing 7 demonstrates how to use this function. You should call rememberMe()
before performing any other session-related activity. Typically this would appear in your global bootstrapping script.
Listing 7 Changing session behaviour to remember the cookie for 7 days (listing-7.php)
<?php
require_once('Zend/Session.php');
$seconds = 60 * 60 * 24 * 7;
Zend_Session::rememberMe($seconds);
?>
The forgetMe()
function is the opposite of rememberMe()
- it changes the session cookie so it will be removed when the browser is closed.
Increasing the PHP Session Garbage Collection Time
Every time a new session is created, a new file is written to the server to hold the session data. Over time this can result in a large number of files. To combat this, PHP has a garbage collection system that automatically deletes untouched session files (files that haven't been updated) after a specified amount of time. By default this time is 24 minutes (1440 seconds).
If the garbage collection time is too low then extending the length of the session cookie will have no effect, since the session data will no longer be stored on the server. To deal with this, you must ensure the PHPsession.gc_maxlifetime
setting is at least the same value as the value passed to rememberMe()
.
In the previous listing, we used a value of 7 days (604800 seconds). In your PHP configuration (either inphp.ini
file, your Apache httpd.conf
file, or in a .htaccess
file), use the setting in Listing 8.
Listing 8 Changing the garbage collection time to 7 days (.htaccess)
php_value session.gc_maxlifetime 604800
Caution: Ensure your sessions are written to a different filesystem location than for other web sites, since another site will likely use the lower garbage collection time, thereby resulting in your sessions being cleaned-up anyway.
You must be aware though that increasing the garbage collection time will result in a much larger number of session files stored at any one time. You should monitor your server after making this change to ensure not too much space is used.
An Example of Implementing "Remember Me"
Now that you know how to implement "remember me" functionality, let's look at a solid example. Many sites that offer this functionality ask the user if they want to be remembered. This example will offer that also.
Listing 9 shows the form you might use for logging in. This form consists of inputs for username and password, as well as the option to remember the user and a submit button.
Listing 9 A log in form with the option to remember the user (listing-9.php)
<form method="post" action="login.php">
<div>
Username:
<input type="text" name="username" />
Password:
<input type="password" name="password" />
<label>
<input type="checkbox" name="remember" value="1" />
Remember Me
</label>
<input type="submit" value="Log In" />
<div>
</form>
Next we process this form, as shown in Listing 10. We'll skip the details here for authenticating a user by using a fictional log_in_user()
function. If the user successfully logs in, we then check whether or not they want to be remembered. If they do, we call rememberMe()
, otherwise we call forgetMe()
.
Note: Technically you probably don't need to call forgetMe()
since the default PHP setting is to expire the cookie on browser close anyway.
This code is based on the code in Listing 3.
Listing 10 Processing the user log in and whether or not they want to be remembered (login.php)
<?php
$username = $_POST['username'];
$password = $_POST['password'];
if (log_in_user($username, $password)) {
require_once('Zend/Session.php');
$remember = isset($_POST['remember']) && $_POST['remember'];
$seconds = 60 * 60 * 24 * 7;
if ($remember) {
Zend_Session::RememberMe($seconds);
}
else {
Zend_Session::ForgetMe();
}
$session = new Zend_Session_Namespace('identity');
$session->username = $username;
header('Location: members.php');
exit;
}
else {
}
?>