zored
zored

Reputation: 3064

PHP strict unserialize

I have a class with typo that is stored in MemCached. Here is example:

class Person { public $n1ame; }
echo serialize(new Person());

I fix typo in next code version:

class Person { public $name; }
var_dump(unserialize($previousSerializedPersion));

But here is what happens: PHP implicitly added unexisting field to my object:

object(Person)#1 (2) {
  ["name"]=>
  NULL
  ["n1ame"]=>
  NULL
}

My person got additional field with data. What I expect is an exception.

Is there any way to achieve that?

Upvotes: 4

Views: 180

Answers (1)

Scuzzy
Scuzzy

Reputation: 12332

Three Suggestions:

1.) Perform manual string translations on your serialized data string to correct it before you call unserialize().

O:6:"Person":1:{s:5:"n1ame";N;}

the s:5 is the character length of the property n1ame in the original serialization, you will need to change it to s:4 to restore it back to name, The s is for string data type, the number is the length of the text value, in this case the property key.

O:6:"Person":1:{s:4:"name";N;}

you could try

unserialize( str_replace( 's:5:"n1ame"', 's:4:"name"', $previousSerializedPersion ) );

2.) Another solution is a __wakup() function to correct your data. This function is run on your object after serialization but before it is assigned and used, This might be a "better" solution as its layed cleanly out in code.

class Person
{
  public $name;
  public function __wakeup()
  {
    if( property_exists( $this, 'n1ame' ) )
    {
      $this->name = $this->n1ame;
      unset( $this->n1ame );
    }
  }
}

unserialize('O:6:"Person":1:{s:5:"n1ame";s:4:"mark";}');

3.) Using the same __wakup() concept but throwing an Exception.

class Person
{
  public $name;
  public function __wakeup()
  {
    if( property_exists( $this, 'n1ame' ) )
    {
      throw new Exception('oh no this data is bad');
    }
  }
}

unserialize('O:6:"Person":1:{s:5:"n1ame";s:4:"mark";}');

https://3v4l.org/h8pss

Upvotes: 6

Related Questions