Closed hamedghaderi closed 7 months ago
Looking at the PR, it seems to be a harmless change. Thinking about maintainability though, I'm wondering how you came across that error to begin with. What even is __PHP_Incomplete_Class
? The info I found was almost none. Can you perhaps describe how to reproduce this?
@UlrichEckhardt,
__PHP_Incomplete_Class
: this is a special PHP object that is used when an attempt is made to unserialize an object whose class definition is not available or not known at the time of unserialization. Essentially, it acts as a placeholder for the original object.
When PHP serializes objects, it saves the class name along with the object's properties. Upon unserialization, PHP attempts to recreate the object based on this information. If the class definition (i.e., the PHP code that defines the class) is not present or cannot be autoloaded, PHP cannot fully reconstruct the object. Instead, it returns an instance of __PHP_Incomplete_Class
, which contains all the properties that were serialized but lacks the methods and class-specific behavior since PHP does not know what the original class was supposed to be.
The occurrence of the __PHP_Incomplete_Class
error in our application stems from our multi-step model construction process. In this process, we incrementally validate and assemble different segments of a PHP class, with each validation step contributing to the formation of the model. To facilitate user progress through these steps, we temporarily store the partially completed model in the session.
This approach allows us to preserve and reuse the already validated segments of the model, ensuring that the user does not need to re-enter data upon encountering a validation error. It is only upon reaching the final step that we compile the fully qualified PHP class and persist it to the database.
@UlrichEckhardt To add clarity to our approach, let's consider a simplified example similar to our implementation. In our application, to persist user progress and validated data between these steps, we employ session storage:
function saveModelToSession($model) {
$sessionData = $this->session->get('model_data');
$modelClass = get_class($model);
if (!isset($sessionData[$modelClass])) {
$sessionData[$modelClass] = [];
}
$sessionData[$modelClass][$model->id] = $model;
$this->session->set('model_data', $sessionData);
}
Hey, thanks for investigating this and making a PR.
To reproduce this you can simply call unserialize()
with a non-existent serialized class:
unserialize('O:3:"Foo":0:{}'); // __PHP_Incomplete_Class(Foo)
Released Clockwork 5.2.1, including this fix.
We have encountered an issue with Clockwork where serialization fails under certain conditions. This problem appears to stem from incomplete object representations during operations that require serialization.