PHP - why can't I get rid of this session id cookie?

Nathan Long picture Nathan Long · Oct 21, 2010 · Viewed 13.7k times · Source

I'm trying to troubleshoot a logout function for a web app. When you're logged in, the app has several cookies set for its domain. Here's the current logout procedure:

  • You click a link, which sends you to a logout page
  • The logout page runs a function that calls session_destroy() and also loops through all the cookies for the domain and sets them to expire in the past (see code below)
  • The logout page then redirects to a login page, which is straight HTML.

At the end of this process, all the other cookies are unset, but the PHPSESSID cookie is still there, has the same value, and is still set to expire at the end of the session.

What am I missing here?

Here's the logout function I mentioned above:

function log_out_current_user() {

        // Destroy the session
        if (isset($_SESSION)) {
            session_destroy();
        }

        // Expire all of the user's cookies for this domain:
        // give them a blank value and set them to expire
        // in the past
        if (isset($_SERVER['HTTP_COOKIE'])) {
            $cookies = explode(';', $_SERVER['HTTP_COOKIE']);
            foreach($cookies as $cookie) {
                $parts = explode('=', $cookie);
                $name = trim($parts[0]);
                setcookie($name, '', time()-1000);
                setcookie($name, '', time()-1000, '/');
            }
            // Explicitly unset this cookie - shouldn't be redundant,
            // but it doesn't hurt to try
            setcookie('PHPSESSID', '', time()-1000);
        }

    }

Answer

NikiC picture NikiC · Oct 21, 2010

You are not removing it with the same parameters as it was created. Use session_get_cookie_params to obtain those. To be portable you should get the name of the cookie via session_name. Here's a small script to do that:

$params = session_get_cookie_params();
setcookie(session_name(), '', 0, $params['path'], $params['domain'], $params['secure'], isset($params['httponly']));