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

 

 

Contributor tasks needed
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

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

yched’s picture

Title: Isolate 5.4 bug when Field / FieldInstance use Serialize interface » Isolate bug on PHP 5.4 if Field / FieldInstance use Serialize interface

better title

Berdir’s picture

Issue tags: +PHP 5.4

Tagging.

Crell’s picture

Note 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. :-)

sun’s picture

Title: Isolate bug on PHP 5.4 if Field / FieldInstance use Serialize interface » Fatal error when using Serializable interface on PHP 5.4
Category: Task » Bug report
Priority: Normal » Critical

IMHO, 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():

  public function __sleep() {
    // Don't serialize the url generator.
    $this->urlGenerator = NULL;

    return array_keys(get_object_vars($this));
  }

→ 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.

catch’s picture

Priority: Critical » Major

This 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.

Damien Tournoud’s picture

This is possibly related to https://bugs.php.net/bug.php?id=67072 that was fixed a few days ago.

heddn’s picture

Issue summary: View changes
Issue tags: -PHP 5.4 +Needs issue summary update, +Novice
heddn’s picture

Todd Zebert’s picture

Assigned: Unassigned » Todd Zebert

I'm working with team Valerie, Matt, and Todd at the #DrupalConLA mentored core sprint.

vgriffin’s picture

Need to look at definition of __sleep, and places that use versions that define fake serialize.

m4olivei’s picture

Here is a patch that reverts the relevant changes that went into #2071969: Serialize interface not reliable.

m4olivei’s picture

Status: Active » Needs review
janter’s picture

Assigned: Todd Zebert » janter

At sprint in LA. Will test.

janter’s picture

Assigned: janter » Unassigned
aburrows’s picture

Assigned: Unassigned » aburrows
Status: Needs review » Closed (duplicate)

Can close this ticket in favour of: https://www.drupal.org/node/1977206