Problem/Motivation
#2071969: Serialize interface not reliable contains a hotfix for entity forms being broken on 5.4 when the form includes an image field or an entity_ref field:
- #2015697-39: Convert field type to typed data plugin for file and image modules
- #2025451: Drupal\entity_reference\Tests\EntityReferenceAdminTest fails on PHP 5.4.9 and libxml 2.9.0
The failures are caused by a corrupt unserialized $form_state at submit time.
Detective work by @claudiu.cristea & @Berdir pointed to the serialization of Field / FieldInstance structures contained within FieldItem classes.
#2071969: Serialize interface not reliable moves Field & FieldInstance config entities from Serialize interface & serialize() / unserialize() methods to __sleep() / __wakeup() methods, which fixes the bug.
It's not exactly clear what is happening though. This seems related to the fact that Serialize interface behaves subtly but critically differently between 5.3 & 5.4. From http://www.php.net/ChangeLog-5.php#5.4.0:
"Added support for object references in recursive serialize() calls. (https://bugs.php.net/bug.php?id=36424)"
What this means is that PHP 5.3 fails to preserve object identity when the same object appears at different places that are handled by separate calls to the serialize() function - which is typically the case for objects that handle their serialization through Serialize interface: the serialize() method typically includes a standalone call to the serialize() function.
http://3v4l.org/D7HIa has a code snippet that directly shows the behavior.
On 5.3, references to the same object before serialization come out as references to different objects after unserialization.
On 5.4, "same object" before serialization comes out as "same object" after serialization.
I still don't have a clear explanation why using the Serialize interface works in 5.3 and produces corrupt unserialized $form_state in 5.4. It's supposed to be the other way around (Serialize preserves object identity in 5.4 and breaks it in 5.3)...
Proposed resolution
Remaining tasks
Task | Novice task? | Contributor instructions | Complete? |
---|---|---|---|
Create a patch by rolling back #2071969: Serialize interface not reliable | Novice | Instructions | |
We should try to isolate a more skinned-down version of the bug (without $entity / $form_state) and add an explicit "unit-test"-like case | Instructions | ||
Review patch to ensure that it fixes the issue, stays within scope, is properly documented, and follows coding standards | Instructions |
User interface changes
n/a
API changes
n/a
Comment | File | Size | Author |
---|---|---|---|
#11 | serialize_fatal_error-2074253-10.patch | 1.78 KB | m4olivei |
Comments
Comment #1
yched CreditAttribution: yched commentedbetter title
Comment #2
BerdirTagging.
Comment #3
Crell CreditAttribution: Crell commentedNote that Drupal 8 will be targeting PHP 5.4 now, so we don't need to worry about differences between 5.3 and 5.4. We do need to worry about making it work properly in 5.4, though. :-)
Comment #4
sunIMHO, we have to figure out the root cause of this, because
Serializable
is the modern replacement for__sleep()
and__wakeup()
, and it should be used instead of the legacy magic methods.The fatal error most likely means that we're trying to serialize the objects in a faulty way, missing a unserializable property somewhere in the inheritance stack.
For example, one key difference is that the current state of the object should not be touched when using Serializable, which currently happens in
Entity::__sleep()
:→ Any call to
serialize()
will kill the urlGenerator on the Entity object, which can't be right?Since we're dealing with pretty large and complex inheritance stacks, it might be worth to investigate the user comment for serializing parent and child classes.
Comment #5
catchThis isn't a critical bug - there's no critical functional issue at the moment. So it's either a major bug or critical task, going for major bug for now.
Comment #6
Damien Tournoud CreditAttribution: Damien Tournoud commentedThis is possibly related to https://bugs.php.net/bug.php?id=67072 that was fixed a few days ago.
Comment #7
heddnComment #8
heddnComment #9
Todd Zebert CreditAttribution: Todd Zebert as a volunteer and at Miles commentedI'm working with team Valerie, Matt, and Todd at the #DrupalConLA mentored core sprint.
Comment #10
vgriffin CreditAttribution: vgriffin as a volunteer commentedNeed to look at definition of __sleep, and places that use versions that define fake serialize.
Comment #11
m4oliveiHere is a patch that reverts the relevant changes that went into #2071969: Serialize interface not reliable.
Comment #12
m4oliveiComment #13
janter CreditAttribution: janter as a volunteer commentedAt sprint in LA. Will test.
Comment #14
janter CreditAttribution: janter as a volunteer commentedComment #15
aburrows CreditAttribution: aburrows commentedCan close this ticket in favour of: https://www.drupal.org/node/1977206