3

if I do serialize($obj), I get:

Serialization of 'Closure' is not allowed

Is there any way these closures can be ignored when serializing? I don't need them when I unserialize the string anyway (value of those properties can be null or whatever).

My class looks smth like this:

Class Node{

  protected $attrs = array();

}

$attrs is an associative array that can contain some elements that are closures, like $attrs['validator'] = function(){...}

Anna K.
  • 1,887
  • 6
  • 26
  • 38

4 Answers4

9

It's simple: You can't. A closure is not serializable. If you want to create "something similar", you can use objects of a class implementing __invoke() instead of the closures.

If you don't need the closures (or you can recreate them yourself while unserializing) you can implement Serializable and don't take the closures into account while serializing. This interface (implementing serialize() and unserialize()) should be prefered over __sleep()/__wakeup().

KingCrunch
  • 128,817
  • 21
  • 151
  • 173
3

I've written a function that allows any Exception to be serialized. This is done by flattening complex values in the backtrace.

Source:

https://gist.github.com/Thinkscape/805ba8b91cdce6bcaf7c

Usage:

<?php
try {
    // exception gets thrown here, i.e.
    // throw new Exception(); 
} catch (Exception $exception) {
    flattenExceptionBacktrace($exception);
    $serialized = serialize($exception);

    $unserialized = unserialize($serialized);
    print_r($unserialized->getTraceAsString());
}
Artur Bodera
  • 1,662
  • 22
  • 20
2

provide your own implementation of _sleep() and _wakeup methods

Maxim Krizhanovsky
  • 26,265
  • 5
  • 59
  • 89
1

To serialize properties of an object while ignoring closures :

$properties = array_map(function ($property) {
    try {
        return serialize($property);
    } catch (\Exception $e) {
        return null;
    }
}, get_object_vars($this));
Alex83690
  • 758
  • 9
  • 30