PHP, Sessions, __sleep, and Exceptions

Today I ran into a problem where my PHP Application would throw this fatal error:

Fatal error: Exception thrown without a stack frame in Unknown on line 0

Which is so much fun, because it doesn’t have a line number, so I had no direction as to what exactly was causing the problem. Some quick googling came up with this website stating the following error:

Most often, the error will appear if you use an exception handler combined with an error reporting to exception handler by converting it to an ErrorException, then there a suddenly a whole new magnitude of ways to throw errors within the exception handle, especially if E_NOTICE, E_STRICT and/or E_WARNING errors are converted. This form most often occurs when you use variables without first initializing them. This error may be preventable by wrapping the exception handler within a try/catch block.

A second form of this error occurs when you attempt to throw an exception in a destructor. This is well documented in the PHP manual, but this can still be triggered if you accidentally throw an exception:

Manually – calling “throw new Exception(‘hello world’)’ in a destructor

Implicitly – calling a function that throws an exception (e.g. calling function foo() which throws an exception)

Error handler (ErrorException) – instating a user-defined function as an error handler which throws an ErrorException (which is still an error)

The problem was that the code I was working with wasn’t using a registered exception handler, nor a destructor. So I went through the controller I was working with and commented out each line, and one by one brought each line back. After a few minutes I found the problem: I had a class that would save itself to the Session, and that class also had a __sleep method which is invoked on serialization (see PHP manual). Because I hadn’t manually closed my php session with session_write_close() (PHP Manual), PHP would close the session when cleaning up & closing the request, which is executed outside of the stack. My __sleep() function had an error and would throw an exception, leading to the Fatal Error.

It was a little tricky to track down, but made complete sense once I found it.

1 thought on “PHP, Sessions, __sleep, and Exceptions

  1. I had a similar problem not too long ago. Our solution was to call

    register_shutdown_function(‘session_write_close’);

    at the beginning of our bootstrap process.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this:
search previous next tag category expand menu location phone mail time cart zoom edit close