PHP sessions keep data about a visitor on the server between page loads, such as who is logged in or what is in their cart, while the browser holds only a random session ID in a cookie. Getting them right is mostly about order and security: configure the cookie before the session starts, start it before any output, and replace the ID when someone logs in.
Set cookie options and session.use_strict_mode before session_start(), and call it before any output. Use Secure, HttpOnly and SameSite=Lax cookies, call session_regenerate_id(true) at login, and at logout clear $_SESSION, expire the cookie and call session_destroy(). Keep only small values such as a user ID in the session, and enforce your own idle timeout rather than relying on garbage collection.
This page is the short version. For complete PHP 8 code covering timeouts, session locking and safe "remember me" tokens, read Master PHP sessions with ease. For the settings on our cPanel servers, read How to use PHP sessions in cPanel.
1. Order matters
The most common session bug is doing things in the wrong order. Cookie parameters and session.* settings only take effect if they are set before session_start(). Once the session has started, session_set_cookie_params() and ini_set('session.…') have no effect on it and raise a warning. And session_start() sends a cookie header, so it must run before any HTML, blank line or echo, or PHP reports "headers already sent".
2. A correct secure login example
<?php
declare(strict_types=1);
// 1. Configure first
ini_set('session.use_strict_mode', '1');
ini_set('session.use_only_cookies', '1');
session_set_cookie_params([
'lifetime' => 0,
'path' => '/',
'secure' => true, // HTTPS only
'httponly' => true, // not readable by JavaScript
'samesite' => 'Lax',
]);
// 2. Then start, before any output
session_start();
// 3. After the password has been checked with password_verify()
function log_in(int $userId): void
{
session_regenerate_id(true); // new ID, old session removed
$_SESSION['user_id'] = $userId;
$_SESSION['last_activity'] = time();
}
// 4. Read safely
$userId = $_SESSION['user_id'] ?? null;
// 5. Log out completely
function log_out(): void
{
$_SESSION = [];
$p = session_get_cookie_params();
setcookie(session_name(), '', [
'expires' => time() - 3600,
'path' => $p['path'],
'domain' => $p['domain'],
'secure' => $p['secure'],
'httponly' => $p['httponly'],
'samesite' => $p['samesite'],
]);
session_destroy();
}3. Security rules that matter
4. Timeouts and garbage collection
session.gc_maxlifetime controls when old session data may be cleaned up; it is not a reliable timeout. Store the time of the last request in the session and log the user out yourself when the gap is too long. The full handbook has a ready-made idle and absolute timeout.
5. Locking and slow pages
With the default file storage, PHP locks the session from session_start() until the script ends, so parallel AJAX requests from one user wait for each other. Call session_write_close() as soon as you have finished writing, or start read-only pages with session_start(['read_and_close' => true]).
6. Storage options
Files are the default and work well on a single server. Sessions can also live in a database, through a class that implements SessionHandlerInterface, or in Redis or Memcached when several servers must share them. In frameworks such as Laravel and Symfony, use the framework's session layer and apply the same cookie and ID rules in its configuration.
7. Running sessions on Domain India
Sessions work out of the box on Domain India shared hosting with file storage; on our cPanel servers they are kept outside your website folders and cleaned up automatically, and the default lifetime is 24 minutes of inactivity. Free SSL is included, which the Secure flag needs. Change session.* settings with ini_set() before session_start(), a .user.ini file, or cPanel's MultiPHP INI Editor; a php_value line in .htaccess causes a 500 error because PHP runs through PHP-FPM or CGI. Shared hosting has no Redis or Memcached, so use files or a MySQL handler there, or a VPS if you need Redis.
- 25 GB NVMe SSD Storage
- 50 GB Monthly Bandwidth
- 1 Website
- 10 Email Accounts
The card shows the live price, excluding 18% GST.
Frequently asked questions
Why do session_set_cookie_params() and ini_set() not change my session?
They must be called before session_start(). Once a session is active, PHP ignores changes to its cookie parameters and session settings and raises a warning. Configure first, then start the session.
When should I call session_regenerate_id()?
Call session_regenerate_id(true) whenever a user logs in, logs out or gains extra privileges. Passing true deletes the old session, so an ID that was stolen or planted before login stops working.
How do I log a user out completely in PHP?
Empty $_SESSION, expire the session cookie with setcookie() using the same path and domain, then call session_destroy(). session_destroy() alone leaves the cookie in the browser and the data in $_SESSION for the rest of the request.
Is session.gc_maxlifetime a session timeout?
Not a reliable one. It only sets when old session data becomes eligible for clean-up, which runs on a schedule or a probability. Store the last activity time in the session and enforce your own timeout.
Can I store PHP sessions in Redis on Domain India shared hosting?
No, shared hosting has no Redis service. Use the default file sessions or a MySQL session handler. On a VPS you can install and run Redis yourself.
Ready to build it properly? Work through Master PHP sessions with ease, fix any "headers already sent" warnings with PHP session and header errors, and host your app on cPanel hosting.
Choose your PHP version per domain, with free SSL for secure session cookies.
See cPanel plans