Ensuring session strict mode in custom SessionHandlerInterface implementation : <h1>Intro</h1>

<p>Since PHP 5.5.2 there is a runtime configuration option (<a href="http://php.net/manual/en/session.configuration.php#ini.session.use-strict-mode" rel="noreferrer">session.use_strict_mode</a>) that is meant to prevent session fixation by malicious clients. When this option is enabled and the <a href="http://php.net/manual/en/session.configuration.php#ini.session.save-handler" rel="noreferrer">native session handler</a> is used (files), PHP will not accept any incoming session ID that did not previously exist in the session storage area, like so:</p>

<pre><code>$ curl -I -H "Cookie:PHPSESSID=madeupkey;" localhost
HTTP/1.1 200 OK
Cache-Control: no-store, no-cache, must-revalidate
Connection: close
Content-type: text/html; charset=UTF-8
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Host: localhost
Pragma: no-cache
Set-Cookie: PHPSESSID=4v3lkha0emji0kk6lgl1lefsi1; path=/  &lt;--- looky
</code></pre>

<p>(with <code>session.use_strict_mode</code> disabled, the response would have <strong>not</strong> included a <code>Set-Cookie</code> header and a <code>sess_madeupkey</code> file would have been created in the sessions directory)</p>

<h1>Problem</h1>

<p>I am in the process of implementing a <a href="http://php.net/manual/en/session.customhandler.php" rel="noreferrer">custom session handler</a> and I'd pretty much like it to adhere to the strict mode, however the interface makes it difficult.</p>

<p>When <code>session_start()</code> is called, <code>MyHandler::read($session_id)</code> is invoked down the line, but <code>$session_id</code> can be <strong>either</strong> the value fetched from the session cookie <strong>or</strong> a new session ID. The handler needs to know the difference, because in the former case an error must be raised if the session ID cannot be found. Moreover, according to spec <code>read($session_id)</code> must return either the session contents or an empty string (for new sessions), but there seems to be no way to raise an error up the chain.</p>

<p>So to sum up, the questions I need to answer in order to match the native behavior are:</p>

<ol>
<li><p>From the context of <code>read($session_id)</code>, how can I tell the difference between a newly minted session ID or a session ID that came from the HTTP request?</p></li>
<li><p>Given a session ID that came from the HTTP request and supposing that it was not found in the storage area, how would I signal an error to the PHP engine so that it would call <code>read($session_id)</code> again with a new session ID?</p></li>
</ol>
