Call session_id($id) only before session_start(), and only with an ID that the active save handler accepts. If PHP creates a different session on every request, log the ID at each boundary and check the warning log before blaming redirects or URL rewriting.
Last updated: November 9, 2026.
<?php
$candidate = $_COOKIE[session_name()] ?? '';
if ($candidate !== '' && preg_match('/\A[-,a-zA-Z0-9]{1,128}\z/', $candidate)) {
session_id($candidate);
}
if (!session_start()) {
throw new RuntimeException('Session storage could not be opened');
}
error_log('active session=' . session_id());The regular expression matches the character set accepted by PHP’s file session handler. Another handler can impose different rules, so prefer the cookie PHP already issued instead of inventing IDs in application code.
Check the identifier and the order of calls
The PHP session_id reference requires the setter to run before session_start(). It also notes that the file handler accepts only letters, digits, comma, and hyphen. An ID copied from a UUID library can contain unsupported punctuation, and a warning may be hidden when production error display is disabled.
The session_start documentation explains that PHP resumes a session from a request identifier and then asks the configured save handler to read it. Inspect session.save_handler, session.save_path, file ownership, and the handler’s own logs. A writable local development directory does not prove that shared hosting can read the same session store.
Verify the cookie across two requests
In browser developer tools, confirm the response sets the expected session cookie and the next request sends it back to the same host and path. Review Secure, SameSite, domain, and path attributes. A cookie scoped to another hostname makes every request look new even though the PHP code is correct.
Do not accept arbitrary session IDs from query strings. Enable strict mode, let PHP generate IDs, and regenerate after authentication. If an integration must resume an ID, authenticate that handoff separately and validate the value before using it. Compare CLI and web php.ini files because they can select different handlers and save paths.