phpsessionserializationapc

__PHP_Incomplete_Class_Name wrong


We're randomly getting some very strange error logs. They don't happen on every page hit, even with the same parameters/actions/etc, and they don't seem repeatable, each one is different in its crash location, and context. But almost all have incorrect __PHP_Incomplete_Class_Name as the cause.

One such error is:

main(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "LoginLogging" of the object you are trying to operate on was loaded before unserialize() gets called or provide a __autoload() function to load the class definition

The problem being, there is no "LoginLogging" class. The object it's referring to was of type ScormElement when it was saved into the session. Doing a dump of the variable gives:

__PHP_Incomplete_Class::__set_state(array(
 '__PHP_Incomplete_Class_Name' => 'LoginLogging',
 'intUserId' => '64576',
 '__intUserId' => '64576',
 'intScormId' => '665',
 '__intScormId' => '665',
 'intScoId' => '9255',
 '__intScoId' => '9255',
 'strElement' => 'cmi.core.lesson_location',
 '__strElement' => 'cmi.core.lesson_location',
 'strValue' => '1',
 'dttTimeModified' => QDateTime::__set_state(array(
   'blnDateNull' => false,
   'blnTimeNull' => false,
   'strSerializedData' => '2011-08-31T08:05:22-0600',
   'date' => '2011-08-31 08:05:22',
   'timezone_type' => 1,
   'timezone' => '-06:00',
 )),
 '__strVirtualAttributeArray' => array (),
 '__blnRestored' => true,
 'objUser' => NULL,
 'objScorm' => NULL,
)

All the properties are retained correctly, and match the class definition for ScormElement. But the class name is wrong. There is no class named LoginLogging.

What is causing this and how do we fix it???

Edit: This is just an example. Other errors are very similar in structure, but affect other class types, and have different incomplete names. However, ALL incomplete names have the same string length of the correct class name.

Edit 2011-10-27: I'm still seeing these error logs, and have had no success in finding a solution. Any help would be appreciated.

PHP 5.3.3, APC, default session handler.


Solution

  • Hakre's suggestion to look at session_write_close led me to what appears to be a reliable fix:

    register_shutdown_function('session_write_close');
    

    This forces the session to be written out before any memory cleanup and class unloading occurs. This is important due to a change in PHP that can result in a race condition between APC removing class references and PHP writing out the session data: http://news.php.net/php.internals/46999