web php
Session Configuration
Session configuration controls how PHP creates, reads, protects, and stores sessions. In real projects this is usually set once during application bootstrap, before any request code calls session_start().
This matters because sessions often carry login state. A weak session configuration can make session fixation easier, expose session cookies to JavaScript, send cookies over plain HTTP, or make sessions disappear sooner or later than the application expects.
Configure before starting the session
Most session settings must be applied before session_start(). Once the session has started, PHP may already have read the cookie, opened storage, and prepared response headers.
For application code, prefer session_start() options or central bootstrap configuration rather than scattering ini_set() calls through controllers.
<?php
declare(strict_types=1);
ini_set('session.use_strict_mode', '1');
ini_set('session.cookie_httponly', '1');
ini_set('session.cookie_secure', '1');
ini_set('session.cookie_samesite', 'Lax');
$settings = [
'use_strict_mode' => ini_get('session.use_strict_mode'),
'cookie_httponly' => ini_get('session.cookie_httponly'),
'cookie_secure' => ini_get('session.cookie_secure'),
'cookie_samesite' => ini_get('session.cookie_samesite'),
];
foreach ($settings as $name => $value) {
echo $name . ': ' . $value . PHP_EOL;
}
// Prints:
// use_strict_mode: 1
// cookie_httponly: 1
// cookie_secure: 1
// cookie_samesite: Lax
ini_set() is useful in examples and simple applications. In framework or production environments, the same values may live in PHP configuration, environment-specific config files, or framework session settings.
Important security settings
session.use_strict_mode=1 tells PHP to reject unknown session IDs instead of accepting any ID sent by the browser. This helps reduce session fixation risk.
session.cookie_httponly=1 stops browser JavaScript from reading the session cookie. It does not stop all attacks, but it limits the damage from many cross-site scripting bugs.
session.cookie_secure=1 tells the browser to send the session cookie only over HTTPS. Use it for real sites served over HTTPS. In local HTTP-only development, this can make the cookie appear to vanish because the browser refuses to send it.
session.cookie_samesite=Lax is a practical default for many server-rendered applications because it reduces cross-site request risk while still allowing normal navigation to the site. Some embedded or cross-site flows need None, which also requires Secure.
PHP can also receive cookie options directly when starting a session:
<?php
declare(strict_types=1);
$options = [
'cookie_httponly' => true,
'cookie_secure' => true,
'cookie_samesite' => 'Lax',
'use_strict_mode' => true,
];
echo json_encode($options, JSON_PRETTY_PRINT) . PHP_EOL;
// Prints:
// {
// "cookie_httponly": true,
// "cookie_secure": true,
// "cookie_samesite": "Lax",
// "use_strict_mode": true
// }
In a web request, those options would be passed to session_start($options).
Lifetime and garbage collection
Session lifetime has two sides: the browser cookie lifetime and the server-side session data lifetime.
session.cookie_lifetime controls how long the browser keeps the session cookie. A value of 0 means "until the browser session ends".
session.gc_maxlifetime controls how old session data can become before PHP's garbage collection may remove it. If the server removes session data while the browser still has a cookie, the user may appear suddenly logged out.
<?php
declare(strict_types=1);
$cookieLifetimeSeconds = 0;
$serverLifetimeSeconds = 60 * 60 * 2;
echo 'Cookie lifetime: browser session' . PHP_EOL;
echo 'Server lifetime: ' . ($serverLifetimeSeconds / 60) . ' minutes' . PHP_EOL;
// Prints:
// Cookie lifetime: browser session
// Server lifetime: 120 minutes
For login sessions, choose lifetimes deliberately. A banking application and an internal documentation site should not share the same timeout policy.
Session storage
By default, many PHP installations store sessions as files. That is fine for a single server, but it becomes awkward when an application runs on multiple web servers because the next request may hit a different server.
Production applications often move session storage to a shared service such as Redis, Memcached, or a database. That decision affects reliability, performance, cleanup, and deployment. Junior developers are not usually expected to design a full session storage system alone, but they should recognise why "it works on my machine" can fail behind a load balancer.
What to check in a project
Look for where sessions are started. There should be one obvious place that sets options before session_start().
Check that login-related sessions use strict mode, HTTPS-only cookies in production, HTTP-only cookies, and an appropriate SameSite value.
Check the environment. cookie_secure=true is correct on HTTPS, but it can break local HTTP development unless the local environment also uses HTTPS or has a separate development configuration.
Check lifetime expectations. If users are logged out unexpectedly, compare cookie lifetime, server-side garbage collection, framework settings, and any custom session storage TTL.
What you should be able to do
After this lesson, you should be able to explain where session configuration belongs, choose sensible security-focused cookie options, describe strict mode, distinguish browser cookie lifetime from server session lifetime, and recognise when shared session storage is needed.
Practice
Task: Review Session Configuration
Write a small PHP script that reviews a session configuration array and reports whether the most important settings are suitable for a production HTTPS site.
Requirements
- Use
declare(strict_types=1);. - Create a function that accepts a configuration array.
- Check for
use_strict_mode,cookie_httponly,cookie_secure, andcookie_samesite. - Treat
LaxandStrictas acceptable SameSite values for this exercise. - Include one secure production configuration.
- Include one weak configuration that reports at least three problems.
- Print the review results.
Check Your Work
Run the script and confirm that the strong configuration passes while the weak configuration explains what needs to change.
Show solution
This solution keeps the review rules explicit so another developer can see which settings matter and why the weak configuration fails.
<?php
declare(strict_types=1);
/**
* @param array<string, mixed> $config
* @return list<string>
*/
function reviewSessionConfig(array $config): array
{
$problems = [];
if (($config['use_strict_mode'] ?? false) !== true) {
$problems[] = 'Enable strict mode so unknown session IDs are rejected.';
}
if (($config['cookie_httponly'] ?? false) !== true) {
$problems[] = 'Mark the session cookie as HttpOnly.';
}
if (($config['cookie_secure'] ?? false) !== true) {
$problems[] = 'Send the session cookie only over HTTPS.';
}
$sameSite = $config['cookie_samesite'] ?? null;
if (!in_array($sameSite, ['Lax', 'Strict'], true)) {
$problems[] = 'Use a deliberate SameSite value such as Lax or Strict.';
}
return $problems;
}
$production = [
'use_strict_mode' => true,
'cookie_httponly' => true,
'cookie_secure' => true,
'cookie_samesite' => 'Lax',
];
$weak = [
'use_strict_mode' => false,
'cookie_httponly' => false,
'cookie_secure' => false,
'cookie_samesite' => '',
];
foreach (['production' => $production, 'weak' => $weak] as $name => $config) {
$problems = reviewSessionConfig($config);
echo strtoupper($name) . PHP_EOL;
echo $problems === [] ? 'OK' . PHP_EOL : implode(PHP_EOL, $problems) . PHP_EOL;
echo PHP_EOL;
}
// Prints:
// PRODUCTION
// OK
//
// WEAK
// Enable strict mode so unknown session IDs are rejected.
// Mark the session cookie as HttpOnly.
// Send the session cookie only over HTTPS.
// Use a deliberate SameSite value such as Lax or Strict.
In a real project, these values might come from framework configuration instead of an array. The review idea stays the same: find the central session configuration and check that it matches the environment.
Why This Works
The production case proves the expected settings can pass. The weak case proves the function catches missing strict mode, readable cookies, non-secure cookies, and an unclear SameSite policy.