PHP Session
Summary: in this tutorial, you will learn how to work with PHP sessions to preserve the state of the web application across pages during a session.
Introduction to PHP sessions
The HTTP protocol is stateless. For example, when you visit the product page product.php , the web server responds with the page:
Suppose, you click the add to cart button on the product.php page and navigate to the cart.php page, the web server won’t know that you have added the product to the cart.
To persist the information across the pages, the web server uses sessions. In this example, when you click the add to cart button, the web server will store the product on the server.
When you view the cart.php page, the web server gets the products from the session and displays them on the cart.php page:
- First, the web browser requests for the product.php page.
- Second, the web server responds with the product.php page’s content.
- Third, you click the Add To Cart button on the product.php page. The page will send an HTTP request (either POST or GET) to the web server. The web server validates the product and generates a session id. It also creates a new text file on the server to store the information related to the selected product.
- Fourth, the web server responds to the web browser with the PHPSESSID cookie in the response header. If the web browser allows cookies, it will save the PHPSESSID cookie, which stores the session id passed by the web server.
- Fifth, in the subsequent request, for example, when you view the cart.php page, the web browser passes the PHPSESSID back to the web server. When the web server sees the PHPSESSID cookie, it will resume the session with the session id stored in the cookie.
- Finally, the web server returns the cart page with the products that you selected.
Sessions allow you to store data on the web server associated with a session id. Once you create a session, PHP sends a cookie that contains the session id to the web browser. In the subsequent requests, the web browser sends the session id cookie back to the web server so that PHP can retrieve the data based on the session id.
Creating a new session
To create a new session, you call the session_start() function:
session_start();
Code language: HTML, XML (xml)
When the session_start() runs at the first time, PHP generates a unique session id and passes it to the web browser in the form of a cookie named PHPSESSID .
If a session already exists, PHP checks the PHPSESSID cookie sent by the browser, the session_start() function will resume the existing session instead of creating a new one.
Since PHP sends the PHPSESSID cookie in the header of the HTTP response, you need to call the session_start() function before any statement that outputs the content to the web browser.
Otherwise, you will get a warning message saying that the header cannot be modified because it is already sent. This is a well-know error message in PHP.
Where PHP stores session data
By default, PHP stores session data in temporary files on the web server. You can find the location of the temporary files using directive session.save_path in the PHP configuration file.
The ini_get() function returns the value of the session.save_path directive:
echo ini_get('session.save_path');
Code language: HTML, XML (xml)
Or you can call the session_save_path() function:
echo session_save_path();
Code language: HTML, XML (xml)
Typically, the session data is stored in the /tmp folder of the web server e.g, /xampp/tmp .
Accessing session data
Unlike cookies, you can store any data in the session. To store data in the session, you set the key and value in the $_SESSION superglobal array.
For example, in the index.php file, you store the user string and roles array in the session as follows:
session_start(); // store scalar value $_SESSION['user'] = 'admin'; // store an array $_SESSION['roles'] = ['administrator', 'approver', 'editor']; ?> html> head>
title>PHP Session Demo title> head> body> a href="profile.php">Go to profile page a> body> html>Code language: HTML, XML (xml)
- First, create a new session by calling the session_start() function.
- Second, set the session data with the key user and roles to the ‘admin’ and the array [‘administrator’, ‘approver’, ‘editor] .
The index.php displays a link that navigates to the profile.php page. In the profile.php file, you can access session data as follows:
session_start() ?> if (isset($_SESSION['user'])) : ?> p>Welcome = $_SESSION['user'] ?> p> endif; ?> if (isset($_SESSION['roles'])) : ?> p>Current roles: p>
ul> foreach ($_SESSION['roles'] as $role): ?> li>= $role ?> li> endforeach; ?> ul> endif; ?>Code language: HTML, XML (xml)
- First, resume an existing session created in the index.php file.
- Second, accessing session data using the $_SESSION array.
Deleting the session data
Whenever you close the web browser, PHP automatically deletes the session. Sometimes, you want to explicitly delete a session, e.g., when you click the logout link. In this case, you can use the session_destroy() function:
session_destroy();
Code language: HTML, XML (xml)
This session_destroy() deletes all data associated with the current session. However, it does not unset data in the $_SESSION array and cookie.
To completely destroy the session data, you need to unset the variable in $_SESSION array and remove the PHPSESSID cookie like this:
session_start(); // remove cookie if(isset($_COOKIE[session_name()]))< setcookie(session_name(),'',time() - 3600, '/'); > // unset data in $_SESSION $_SESSION[] = array(); // destroy the session session_destroy();
Code language: HTML, XML (xml)
Notice that we used the session_name() function to get the cookie name instead of using the PHPSESSID . This is because PHP allows you to work with multiple sessions with different names on the same script.
Summary
- Sessions allow you to persist data across pages in a web application.
- Call the session_start() function before any statement that outputs to the web browser for creating a new session or resuming an existing session.
- Use the $_SESSION superglobal array to access the session data.
- Call the session_destroy() function to completely delete session data.
Using sessions with php
Sessions are a simple way to store data for individual users against a unique session ID. This can be used to persist state information between page requests. Session IDs are normally sent to the browser via session cookies and the ID is used to retrieve existing session data. The absence of an ID or session cookie lets PHP know to create a new session, and generate a new session ID.
Sessions follow a simple workflow. When a session is started, PHP will either retrieve an existing session using the ID passed (usually from a session cookie) or if no session is passed it will create a new session. PHP will populate the $_SESSION superglobal with any session data after the session has started. When PHP shuts down, it will automatically take the contents of the $_SESSION superglobal, serialize it, and send it for storage using the session save handler.
By default, PHP uses the internal files save handler which is set by session.save_handler. This saves session data on the server at the location specified by the session.save_path configuration directive.
Sessions can be started manually using the session_start() function. If the session.auto_start directive is set to 1 , a session will automatically start on request startup.
Sessions normally shutdown automatically when PHP is finished executing a script, but can be manually shutdown using the session_write_close() function.
Example #1 Registering a variable with $_SESSION .
session_start ();
if (!isset( $_SESSION [ ‘count’ ])) $_SESSION [ ‘count’ ] = 0 ;
> else $_SESSION [ ‘count’ ]++;
>
?>?php
Example #2 Unregistering a variable with $_SESSION .
Do NOT unset the whole $_SESSION with unset($_SESSION) as this will disable the registering of session variables through the $_SESSION superglobal.
You can’t use references in session variables as there is no feasible way to restore a reference to another variable.
Note:
File based sessions (the default in PHP) lock the session file once a session is opened via session_start() or implicitly via session.auto_start. Once locked, no other script can access the same session file until it has been closed by the first script terminating or calling session_write_close() .
This is most likely to be an issue on Web sites that use AJAX heavily and have multiple concurrent requests. The easiest way to deal with it is to call session_write_close() as soon as any required changes to the session have been made, preferably early in the script. Alternatively, a different session backend that does support concurrency could be used.
User Contributed Notes
Session Functions
Be aware of the fact that absolute URLs are NOT automatically rewritten to contain the SID.
Of course, it says so in the documentation (‘Passing the Session Id’) and of course it makes perfectly sense to have that restriction, but here’s what happened to me:
I have been using sessions for quite a while without problems. When I used a global configuration file to be included in all my scripts, it contained a line like this:
which was used to make sure that all automatically generated links had the right prefix (just like $cfg[‘PmaAbsoluteUri’] works in phpMyAdmin). After introducing that variable, no link would pass the SID anymore, causing every script to return to the login page. It took me hours (!!) to recognize that this wasn’t a bug in my code or some misconfiguration in php.ini and then still some more time to find out what it was. The above restriction had completely slipped from my mind (if it ever was there. )
Skipping the ‘http:’ did the job.
OK, it was my own mistake, of course, but it just shows you how easily one can sabotage his own work for hours. Just don’t do it 😉
Sessions and browser’s tabs
May you have noticed when you open your website in two or more tabs in Firefox, Opera, IE 7.0 or use ‘Control+N’ in IE 6.0 to open a new window, it is using the same cookie or is passing the same session id, so the another tab is just a copy of the previous tab. What you do in one will affect the another and vice-versa. Even if you open Firefox again, it will use the same cookie of the previous session. But that is not what you need mostly of time, specially when you want to copy information from one place to another in your web application. This occurs because the default session name is «PHPSESSID» and all tabs will use it. There is a workaround and it rely only on changing the session’s name.
Put these lines in the top of your main script (the script that call the subscripts) or on top of each script you have:
if( version_compare ( phpversion (), ‘4.3.0’ )>= 0 ) <
if(! ereg ( ‘^SESS9+$’ , $_REQUEST [ ‘SESSION_NAME’ ])) <
$_REQUEST [ ‘SESSION_NAME’ ]= ‘SESS’ . uniqid ( » );
>
output_add_rewrite_var ( ‘SESSION_NAME’ , $_REQUEST [ ‘SESSION_NAME’ ]);
session_name ( $_REQUEST [ ‘SESSION_NAME’ ]);
>
?>
How it works:
First we compare if the PHP version is at least 4.3.0 (the function output_add_rewrite_var() is not available before this release).
After we check if the SESSION_NAME element in $_REQUEST array is a valid string in the format «SESSIONxxxxx», where xxxxx is an unique id, generated by the script. If SESSION_NAME is not valid (ie. not set yet), we set a value to it.
uniqid(») will generate an unique id for a new session name. It don’t need to be too strong like uniqid(rand(),TRUE), because all security rely in the session id, not in the session name. We only need here a different id for each session we open. Even getmypid() is enough to be used for this, but I don’t know if this may post a treat to the web server. I don’t think so.
output_add_rewrite_var() will add automatically a pair of ‘SESSION_NAME=SESSxxxxx’ to each link and web form in your website. But to work properly, you will need to add it manually to any header(‘location’) and Javascript code you have, like this:
The last function, session_name() will define the name of the actual session that the script will use.
So, every link, form, header() and Javascript code will forward the SESSION_NAME value to the next script and it will know which is the session it must use. If none is given, it will generate a new one (and so, create a new session to a new tab).
May you are asking why not use a cookie to pass the SESSION_NAME along with the session id instead. Well, the problem with cookie is that all tabs will share the same cookie to do it, and the sessions will mix anyway. Cookies will work partially if you set them in different paths and each cookie will be available in their own directories. But this will not make sessions in each tab completly separated from each other. Passing the session name through URL via GET and POST is the best way, I think.