PHP Sessions explained




You never used PHP Sessions and you want to get started? Or maybe you already use them but you want a better understanding of how they work?

Then this guide is for you.


In this post you will find a simple but complete introduction to Sessions with some examples on how to use them, a more in depth analysis of the most important functions and some facts about security that you should be aware of.












The main purpose of PHP Sessions is to establish a stateful link between a website and the remote clients, with the ability to preserve informations across subsequent client connections.


By using Sessions you can associate a set of variables with the client accessing your PHP script, and automatically restore the same variables the next time the same client will connect again.

Sessions can be used, for example, in e-commerce sites to remember which items each client put in its cart, or in password protected websites to know if a client trying to access the site has already been authenticated.

In these example cases, the first time a client accesses the website a new Session is started. The website’s PHP script can then save some variables along with the Session, for example which items have been put in the cart or a boolean value telling whether valid authentication credentials have been provided by the client.

The next time the same client will access the website, its Session will be restored along with all the previously saved variables. This means that the website’s PHP scripts will know which items have been put in the cart or if the client is authorized to access the protected site.


Now let’s see how to use Sessions in practice.







Sessions are enabled by default in most PHP installations. Every PHP script can use Sessions, command line scripts (like PHP daemons) being the only relevant exception (the reason is that Sessions use cookies to identify remote users, which are not available in the CLI environment).


Using Sessions is very simple.

The first thing you need to do in your PHP script is to start a Session with the session_start() function. Every single remote client has its own Session, and session_start() takes care of checking if a Session has already been started for the currently connected client; in that case its Session is restored, otherwise a new one is created.

After starting a Session, the $_SESSION superglobal array becomes available. This is where you can store all the Session’s related variables, as all variables inside this array will be saved and retrieved the next time the same client will connect.

This is basically all you need to know to start using Sessions, at least as a start.

Now let’s see a basic example.



Suppose you would like to know how many times the currently connected client has visited your page. For doing that you first you need to identify the client, then you need to keep track of how many times that very client has connected to your page.

Remote client identification is automatically done simply by starting a Session with session_start().

That will also create the $_SESSION superglobal array, the one place where all the Session’s data can be stored and retrieved. Each different remote client has its own $_SESSION array, which is properly created and populated every time the same client accesses your page.

Keeping track of each client’s page accesses is just a matter of starting a Session and using a numeric variable inside the $_SESSION array. For example, you could use $_SESSION[‘visits’] for that purpose.

Using a normal variable like $visits wouldn’t work, because it would be destroyed at the end of the script execution and never retrieved.


The first time a client accesses the page the $_SESSION array will be empty and the ‘visits’ key won’t exists. If this is the case you need to initialize it to 0, otherwise you just need to increment it by 1.


Here is the code:


/* Start the Session */
/* Check whether we already set 'visits' for this remote client */
if (!array_key_exists('visits', $_SESSION))
   $_SESSION['visits'] = 0;
echo 'You visited this page ' . $_SESSION['visits']++ . ' times.';


Easy, isn’t it?


Let’s see another basic example. Suppose you have a private page, and that you want to show its content to authorized clients only. The remote client must provide proper user and password to view the page’s content.

If the remote client isn’t authenticated then the PHP script will show a login form, otherwise it will show the private content.


One way to do that would be to always check for user and password, but that would force the client to provide them in the request string every time it accesses the page.
Instead, you want the client to provide its credentials just once, and then be able to access the private content directly.

This can be done easily with Sessions (note: this is not meant to be the proper way to authenticate users, but just an example of how Sessions work!)


Here is the PHP code:


/* Start the Session */
/* Is the client authenticated? */
$auth = FALSE;
/* Check the Session array to see if this client is already authenticated */
if (array_key_exists('auth', $_SESSION))
   $auth = TRUE;
   /* Check the request string for user and password */
   $user = '';
   $passwd = '';
   if (array_key_exists('user', $_REQUEST))
      $user = $_REQUEST['user'];
   if (array_key_exists('passwd', $_REQUEST))
      $passwd = $_REQUEST['passwd'];
   /* Example authentication */
   if (($user == 'user') && ($passwd == 'passwd'))
      $auth = TRUE;
      /* Save the authorized state in the Session array */
      $_SESSION['auth'] = TRUE;
if ($auth)
   echo 'Here is your private content.';
   /* Show the login form */
   Please login:<br>
   <form method="POST">
   <input type="text" name="user">
   <input type="password" name="passwd">
   <input type="submit" value="Log-in">


In this example, the boolean $auth variable is set to TRUE if the remote client is authorized to access the private content. That happens in two cases: when the client actually sends the user and password request strings, and when the Session variable $_SESSION[‘auth’] is set.

When the remote client authenticates itself with user and password, the script sets the Session’s auth variable $_SESSION[‘auth’]. This way, when the same client will access the page again it won’t have to send user and password again, but its Session state will “remember” that it has already been authorized.

Of course, unsetting $_SESSION[‘auth’] will force the remote client to send its credentials again.


Now you should have an idea of how Sessions work in practice. Let’s move on to the next section.






Session facts




There are a few important facts about Sessions that you should know before using them:


  • $_SESSION variable types
    You can store all variable types inside the $_SESSION global array as long as they are serializable. Not serializable types include local and remote file handles, database connection resources, sockets and so on. These variable types cannot be stored and retrieved across subsequent client accesses.


  • $_SESSION scope
    $_SESSION is a superglobal array: this means that it’s accessible from anywhere inside your PHP script (including from inside functions and classes) without the need to declare it global.


  • Cookies
    Sessions use cookies to identify remote clients. That means that Sessions won’t work if the client’s web browser doesn’t accept cookies.


  • Session locking

    PHP keeps Sessions’ data inside files. PHP scripts needs to acquire an exclusive lock on the data file relative to the current Session, and other scripts (or other instances of the same script) cannot acquire the same lock before it’s released.
    In other words, scripts executed by the same remote client cannot use Sessions at the same time but must wait for the previous script to terminate.
    This can cause delays in some cases, for example when a web page sends many simultaneous AJAX connections. In that case, every AJAX backend (if it uses Sessions) needs to wait for the previous one to terminate before being able to create its own Session.
    In the next chapter you will see how this situation can be mitigated.


  • Sessions cookie lifetime
    How long does a Session lasts? The Session lifetime is the maximum time interval from when the Session is created for the first time until it expires. When a Session expires, all the variables inside $_SESSION are destroyed and lost, and the cookie used for client identification is no longer valid. A new Session must therefore be created.
    A new remote client who hasn’t a Session yet and a remote client whose Session is expired can be treated the same as long as the PHP code is concerned, as in both cases no Session exists for that client and a new one must be created.
    By default, a Session will only last until the remote client will close its browser. This may or may not the best setting for your application, depending on how you want to use Sessions. In the next chapter you will see how you can change this value.







There are many Sessions related functions that can be used to customize Sessions’ workflow, but just few of them are commonly used in real scenarios.

Many of these functions solve very specific needs (like session_reset() that re-initialize the $_SESSION array with its original values), and it doesn’t make sense to learn all of them right from the start. You can just go and check them when you will need to.

Some other functions are security related, for example session_regenerate_id(), but we will talk about security in the last chapter.


The most useful Sessions related functions are session_start(), session_name(), session_set_cookie_params() and session_write_close(). These are the ones that you will probably have the chance to use.




session_start() starts the remote client’s Session and makes the $_SESSION global array available, as already explained. If no Session already exists for the currently connected client then a new one will be created, otherwise the existing one will be restored.

This function takes as optional argument an array of Sessions options that override the default ones. We will see shortly which of these options are worth considering.

On top of that, the options array passed to session_start() can also have an additional key: ‘read_and_close’. If this option is set to TRUE, then the Session data (i.e., the $_SESSION array) will be read-only.

Remember how multiple instances of the same Session cannot be executed at the same time? This option can help with that. If you just need to read Session data without making any changes, this option will limit the Session lock time to the initial read phase only.
If your web application has many concurrent HTTP requests (usually AJAX calls), then this option may be useful for maximising the response time.

It’s important to keep in mind that session_start() must be called before any output is sent to the browser. This is a common source of errors, for example if the PHP file has an empty line at the beginning.



session_name() changes the current Session’s name and the name of the Session Cookie sent to the remote browser. This function must be called before session_start(). The default Sessions’ name is “PHPSESSID”.

You may want to change the name of your own Sessions to customize your application’s appearance and the cookie the clients’ browsers will receive.

This is an example on how to set a custom name for your Session:  


/* Set your Session name */
/* Start the Session */
/* Do other things... */


Remember that when closing a Session (you will see later in this post how to do it) you need to clear the proper cookie. If you use a custom Session name, then you need to use that name for clearing the Session Cookie as well.



This function sets some options for the current Session. It can set up to 5 options:

  1. $lifetime
    The lifetime, in seconds, of the Session. This is an important option: it tells how long this Session will remain active. So, if you set this value to 3600, this Session will expire after one hour. This means that if the same remote client will connect more than one hour later, a new Session will be created and the $_SESSION array will be empty. This option is useful, for example, for setting a “login timeout”.
    The lifetime is relative to the first time the session is created, so even if the remote client accesses the page again the Session timeout won’t change (for it to change, you either need to close and start the session again or increment the lifetime value).
    Setting this option to 0 (zero) has a special meaning: the Session will be valid only until the client closes the browser. This is also the default value.


  2. $path
    The site path on where the Session is enabled. For example, if your web application’s URL is, setting this parameter to the default (“/”) will make the Session valid throught the domain. If you set $path to “myapp”, then the Session will be valid only for pages within the path.


  3. $domain
    This option is similar to the previous one, but it refers to the domain itself. Usually you want to leave this parameter to the default value (the domain name of the server), but you can change it to restrict the domain.


  4. $secure
    If this parameter is set to TRUE, then the Session will work over secure connections only (i.e., HTTPS). This is a good idea if your applications deals with sensitive or critical data, as Session Cookies sent over unencrypted connections can be read and used for Session hijacking (see the last chapter for more details).


  5. $httponly
    Setting this parameter to TRUE will send a request to the remote browser to use the Session Cookie for HTTP(S) requests only. This may give you a bit of added security.



This function explicity closes the Session, which is usually done automatically when the script terminates. This is useful for the locking problem we have already talked about: this function let the script “release” the Session lock as soon as possibile, minimizing the time other scripts have to wait for acquiring the lock.

You should call his function when you don’t need to work on Session data anymore and your script still has some execution time left.




You can also customize the global Sessions’ behaviour by changing some of the default settings, either globally in the PHP configuration file (editing the php.ini file) or at runtime.

The full list of options is quite long, but here are the ones you should care about:

  • session.save_path
    This option sets the path where the actual Sessions’ data is stored on the file system. It’s ok to just leave the default value (“/tmp” on Linux and *nix systems), but you should be aware that this may not be the best option for security. We’ll talk about this in the last chapter about security.


    This option sets the same parameter as the session_name() function does. You can change this option globally in order to use your custom Session name by default.


  • session.cookie_lifetime
    This option sets the same lifetime parameter you can set with session_set_cookie_params(). By default, Sessions will remain active only until the remote client closes the browser; while this can be too limiting in many cases, it’s also true that different web applications needs very different Session times. For example, a home banking app may stick with the default, while a less critical service may set a week long value as well. My suggestion is to keep the default as it is and to change it when needed at runtime.


  • session.cookie_path and session.cookie_domain
    We already saw this options before in the session_start() options. If you always use different values from the default ones, it can be a good idea to modify them in the global configuration.








 A Session will automatically expire after the timeout, but you may want to explicitly close it as well (for example when the client “logs out”).

Closing (or destroying) a Session means deleting all the variables inside $_SESSION, deleting the server-side data (the file where PHP stores the Session’s data) and deleting the Session Cookie from the client’s web browser.

Here is how to do it:


/* First start the Session */
/* Unset all $_SESSION variables */
$_SESSION = array();
/* Clear the Session Cookie */
$cookie_par = session_get_cookie_params();
setcookie(session_name(), '', time() - 86400, $cookie_par['path'], $cookie_par['domain'], $cookie_par['secure'], $cookie_par['httponly']);
/* Destroy the session data */


Notice that you need to start the Session before you can destroy it.

Clearing $_SESSIONS (at line 7) deletes all the Session variables, and the session_destroy() function (at line 14) takes care of the server side Session data.

setcookie(), at line 11, tells the remote browser to clear the cookie. The cookie’s parameters are retrieved with the session_get_cookie_params() function as used directly in setcookie().

(Note that setting the cookie timeout in the past makes the remote browser delete the cookie).






Sessions security




Sessions are often used for authentication purposes, for storing and providing private and sensitive data and for other critical applications, so it’s important to understand how secure they really are and how to maximise security.

As far as security is concerned, Sessions have two major weak points: cookie hijacking risk and storage leaking.

Let’s see what kind of risk they are and what you can to do mitigate them.



Cookie Hijacking


Cookie Hijacking refers to the act of stealing a Session Cookie and using it for maliciously accessing a website.

This can be done in a few different ways: sniffing the network (if HTTPS is not used), gaining remote or physical access to the client’s computer, or exploiting a browser security flaw.

Cookie Hijacking can be prevented by using HTTPS (so that all HTTP data, including cookies, are encrypted) and securing the remote computers.

While the use of HTTPS can be enforced by the web server itself, you cannot do very much about remote client’s computers security.


PHP has some ways to mitigate this problems, like dynamically changing the session ID and keeping the lifetime short enough.

Some specific configuration options can help increase Sessions security. Some of them are already set by default, but others are not. I suggest you to enable session.use_strict_mode and, if you are going to use HTTPS only, session.cookie_secure too. This two options (that are not enabled by default) will easily increase Session security without any relevant side effect.

PHP has also more sophisticated tools to go even further, for example dynamically changing the Session ID at every iteration (with session_regenerate_id()), however pushing security too far can create other problems. For example, dynamically changing the Session ID can cause problems with AJAX as the Session ID can change between multiple asynchronous HTTP requests cutting some of them out.

Even with all the security features PHP offers, Sessions can be secured only up to some level and it’s impossible to achieve a very high security level using Sessions only.

If your application needs a high level of security then you have to use only a subset of Sessions functionalities, for example keeping Sessions open only until the remote client closes its browser. Some very critical data should even be kept completely outside the scope of Sessions and should explicitly require user and password to be retrieved.

Have you even noticed how some services (like Google) ask again for your password when you try to access some sensitive data, even if you are already logged in? This happens because the cookie your browser uses to log-in is not secure enough for that data, and a proper authentication (with username and password) is required.



Storage Leaking

The second major security risk is related to storage. By default, PHP saves its Sessions data inside /tmp (on *nix systems like Linux), which is a directory every system user can read. This is indeed not very secure, and you should use a directory readable by the web server only.

You should however keep in mind that the Sessions data can only be as secure as the server itself, so you should avoid keeping sensitive data inside Sessions’ variables in the first place.


This is also one of the reasons I prefer not to use Sessions for user authentication. In my user authentication tutorial I store the cookies on the database (encrypting them in the process), so that there is no way to stole a login cookie from the server (or even from the SQL server, as only the hash is stored).


For maximise security, Sessions’ data should be stored inside a directory readable by the web server only and outside the web directory root. This is critical, otherwise the Sessions’ files could be read from the Internet. 

There could be other ways to even improve storage security, like using encrypted file systems or SANs (storage area networks), but my opinion is that if you are dealing with such critical applications then it would be better not to rely on Sessions in the first place than trying to secure them beyond reasonably possible.



This guide ends here, I hope it can be helpful to you. If you have any questions feel free to ask in the comments below, and if you liked this guide please take a second to share it!


45 thoughts on “PHP Sessions explained”

  1. Very nice explanation, thank you.

    A subsequent update describing session handling involving database storage would be great.


  2. Hi Alex, thank you for your article.
    I have an issue with sessions. On my website I store user privileges in array $_SESSION[‘privileges’]. Then I created a file to change privileges of users. If there is a user with privilege “a”, then he can change to “b”.

    echo”Can’t access”;

    But although I have ‘a’ privilege, sometimes it doesn’t work (randomly). Is it possible that SESSION[‘privileges’] is changed in compile time, before the ‘if’ is evaluated? and then in execution time it evaluates to false, because SESSION[‘privileges’] has already changed to ‘b’? Thank you very much.

    • Hi Seba,
      I exclude the compiler error.
      What I’m noticing is that this line:


      clears all the values from $_SESSION[‘privileges’], and replaces it with a new array containing only the ‘b’ element.
      Are you sure you aren’t removing the ‘a’ element by mistake?

      If this is not the case, I need to see the full code to help you further.

      • Hi Alex, thank you for your fast response. Yes, the idea is to overwrite the privileges. So you won’t be able to access this file again after execution, if you don’t have the privileges in the new user.
        I added this first line:


        echo”Can’t access”;

        this works fine! For some reason, with the first script, it changed the SESSION variable before evaluating the ‘if’.
        Creating a new variable equal to the SESSION solves the problem. I still think this is an issue related with compile and execution time. Any thoughts about it? Thank you!

        • That’s interesting, thank you for sharing.
          Any chance you can send me the whole script? (Removing any sensitive data it may contain). I’d like to test it and see if I get the same issue.

  3. Hi Alex, great info on sessions and settings, which I always have trouble with.
    You say that ‘session close’ is the same as ‘session destroy’, but is that really true? Surely session_write_close() simply closes the session without waiting for the timeout, hopefully future avoiding session_start() clashes – but surely keeps the session data just written?
    Session_destroy() clearly clears the session data. Maybe you could clarify this for me and go over the differences between; session_unset(), session_destroy() and session_write_close().
    Lastly, I have a question about session_start(‘read_and_close’). What is the correct syntax for this(session_start(‘read_and_close’) or session_start(‘read_and_close’=>’true’) and how many session data statements ($data=$_SESSION[‘data’] will this read; just one, or many? Is there a limit?
    Hope you can help, thanks.

    • Hi Rob
      As you say, session_write_close() ends the current Session and writes all the $_SESSION data into storage. This is done to limit Session-locks across multiple scripts.
      session_destroy() is indeed different. It clears all the Session data from storage, effectively forcing the user to start a new Session.
      So, to sum up:

      – session_write_close() simply closes the Session, just like it happens normally at the end of the script execution. The Session can be started again at the next script execution, and the same data will be available into $_SESSION.

      – session_destroy() clears all the current Session variables permanently. The current Session ID is no longer valid, and usually when destroying the Session you also want to unset the current Session cookie from the browser.

      session_unset() is not necessary. You can simply unset specific variables (ex. unset($_SESSION[‘var’])) or clear the whole Session array with $_SESSION=array().

      For your next question, the correct syntax is:

      session_start([‘read_and_close’ => true]);

      So, ‘read_and_close’ must be an element of the options array.
      I’m not sure about your last question. What do you mean with “how many session data statements”?


  4. Hello Alex, I need to know that will the session variable remains the same for the user if we login from different system .
    Is it is System Dependent?

    • The Session is browser-dependent. If you login from a different browser, you will get a different Session.
      To save and restore the same data for registered users, regardless of the browser they use, you need to save the data on the database.

  5. Hello Alex i just hosted my website but it seems the session_start(); function doesn’t work so user signup and login does not work , it however works perfectly on my localhost.Please can you help me

  6. Hi Alex,
    Thank you for the training you did on Sessions!
    I tried using your codes to fix my newly created Reset Password script.

    The code I currently have in the reset password top section of /reset_password.php is blocking/redirecting accesspath, -( that is good for people who are not logged in).
    But it is not recognizing the client who is logged in, as logged in.
    I would appreciate your help,

    ——–Code in the reset password upper section —-


    // variable declaration
    $username = "";
    $email = "";
    $errors = array();
    $_SESSION['success'] = "";

    // Check if the user is logged in, otherwise redirect to login page

    if(!isset($_SESSION["success"]) || $_SESSION["success"] !== true){
    header("location: login.php");

    // Include config file
    require_once "controler2/config.php";

    // Define variables and initialize with empty values
    $new_password = $confirm_password = "";
    $new_password_err = $confirm_password_err = "";

  7. Hi Alex, any advise for using sessions and url parameters?

    I have a url with a parameter /?client_feedback=1 for a specific page, attached to my session I have css variables to show/ hide the page content – related to the specific page. The Problem is when I look at another page on the website and come back to the specific page the content is hidden. How do I get the variable to stay on the specific page after looking at others?

    I have session_start(); set in my header.php as to be on all pages.

    I am using $_SESSION[“client_feedback”] = $_GET[‘client_feedback’]; to get the url parameter.

  8. Hi Alex, very good article. My code:

    var_dump($_SESSION); /*output: array(0) { }

    but in my browser cookie section I find one ‘mySessionName’.
    Tanks a lot.

      • Thanks Alex for the tuts, u called session_name(‘the session name’) in the beginning of the tuts and then you session_start() the session my question here is that what is the meaning of the session_name() and y can’t u put it after session_start() the session_name() and secondly u said it is harmful to store session on browsers that someone might temper with it l, what is the best way of storing such sessions should it be on the database or where ?,
        and how is sessions thesame with cookies,
        Lots of questions I just want to understand what I learned
        Thank you

        • session_name($name) sets a new identifier for the Session.
          This is the name of the cookie used to store the Session ID, which defaults to PHPSESSID.

          You need to call session_name($name) before session_start() because the cookie name must be set before starting the Session and sending or reading the cookie.

          The purpose of this function is to differentiate Sessions. For example, you can use different $_SESSION variable sets in different pages by using different Session names.

          About Sessions security, there are some countermeasures you can take to prevent the most common attacks. Using cookies to store the ID is still the best way compared to set it in URLs.

  9. Thank you!
    I’dont know why, but I assumed that I stay in a session between calls AND this ensure me the access for the session data. (My debug experience with PHP are limited – yet.)

    • Thank you Xonix,

      the Session must be opened in each PHP script.
      The only exception is when you *include* a PHP file inside the main one. In this case, if the Session is opened in the main script it will be available in the included file too.

  10. Hi Alex!
    This is the best clarification about the subject. I’m new in the PHP world, your article was a lifesaver. I have a question. I’m fixing an old JS+PHP code now.
    1. index.php starts with session_start()
    2. then later it calls example.php with POST
    3. example.php starts with session_start()
    According to your explanation the second is unnecessary, and a bad practice. Am I right?

    • Thank you for your comment!

      session_start() must be called in every script where you need to access the Session data.
      In your case, the POST request data sent from index.php to example.php will, of course, be accessible from example.php (in $_POST).

      But if you want to share the $_SESSION array between index.php and example.php, you need to call session_start() in both scripts.

      I don’t think this is a bad practice in any way. Which section of the tutorial make you think so?

  11. Very nice, useful and explicit article, I have a slight issue here. I will like to create session variables (eg user shopping cart items) on my computer and be able to access that same data when i log in using another device. How can i achieve this?

    • Hi Alain,
      Sessions are bound to specific browsers, so the $_SESSION array is not shared between devices.

      However, you can achieve the same result by keeping the session data inside a database.
      The data will be linked to the user. Then, when the same user logs in from another device, you can read back the same data.

      For example, items in the shopping cart can be saved on a “cart” database table with the item ID, the item amount and the user ID.
      Then, when the user logs in again, you read that data back from the db and you rebuild the same cart.

  12. >session_set_cookie_params()

    >This function sets some options for the current Session. It can set up to 5 options:

    > $lifetime
    > The lifetime, in seconds, of the Session.

    True? Session lifetime? Why?!

    • Hi Andrey,

      the lifetime parameter sets the timeout of the Session cookie. After that time, the browser will unset the cookie. If this paramer is 0 then the cookie will be deleted when the browser page is closed.


Leave a Comment