opis / closure

Serialize closures (anonymous functions)
https://opis.io/closure
MIT License
2.5k stars 84 forks source link

Carbon Notice Error: serialize(): __sleep should return an array only containing the names of instance-variables to serialize #75

Open dercoder opened 4 years ago

dercoder commented 4 years ago

Hi,

I get this notice message when I try to use a Carbon DateTime in a closure. It is working! Its just an Notice Error. So its not really important.

I tested it on: Linux PHP 7.3 Windows PHP 7.2

To test it: https://github.com/dercoder/closure-carbon-issue

php test_carbon.php

PHP Notice:  serialize(): __sleep should return an array only containing the names of instance-variables to serialize. in closure-carbon-issue\vendor\opis\closure\src\SerializableClosure.php on line 155
PHP Stack trace:
PHP   1. {main}() closure-carbon-issue\test_carbon.php:0
PHP   2. serialize() closure-carbon-issue\test_carbon.php:20
PHP   3. Opis\Closure\SerializableClosure->serialize() closure-carbon-issue\test_carbon.php:20
PHP   4. serialize() closure-carbon-issue\vendor\opis\closure\src\SerializableClosure.php:155
GrahamCampbell commented 4 years ago

Do you see this issue on PHP 7.4 too?

dercoder commented 4 years ago

Yes, i get more errors here:


PHP Notice:  serialize(): "date" returned as member variable from __sleep() but does not exist in /mnt/c/Users/PhpstormProjects/closure-carbon-issue/vendor/opis/closure/src/SerializableClosure.php on line 155
PHP Notice:  serialize(): "timezone_type" returned as member variable from __sleep() but does not exist in /mnt/c/Users/PhpstormProjects/closure-carbon-issue/vendor/opis/closure/src/SerializableClosure.php on line 155
PHP Notice:  serialize(): "timezone" returned as member variable from __sleep() but does not exist in /mnt/c/Users/PhpstormProjects/closure-carbon-issue/vendor/opis/closure/src/SerializableClosure.php on line 155
PHP Fatal error:  Uncaught Error: Invalid serialization data for DateTime object in /mnt/c/Users/PhpstormProjects/closure-carbon-issue/vendor/nesbot/carbon/src/Carbon/Traits/Serialization.php:131
Stack trace:
#0 /mnt/c/Users/PhpstormProjects/closure-carbon-issue/vendor/nesbot/carbon/src/Carbon/Traits/Serialization.php(131): DateTime->__wakeup()
#1 [internal function]: Carbon\Carbon->__wakeup()
#2 /mnt/c/Users/PhpstormProjects/closure-carbon-issue/test_carbon.php(21): unserialize()
#3 {main}
  thrown in /mnt/c/Users/PhpstormProjects/closure-carbon-issue/vendor/nesbot/carbon/src/Carbon/Traits/Serialization.php on line 131

PHP 7.4.6 (cli) (built: May 14 2020 10:03:35) ( NTS ) Copyright (c) The PHP Group Zend Engine v3.4.0, Copyright (c) Zend Technologies with Zend OPcache v7.4.6, Copyright (c), by Zend Technologies

sorinsarca commented 4 years ago

Since test_datetime.php works, I suspect that the problem is in carbon library.

dercoder commented 4 years ago

The regular serialize() code is working with Carbon: https://github.com/dercoder/closure-carbon-issue/blob/master/test_carbon.php#L12

sorinsarca commented 4 years ago

I'm afraid that the problem is in PHP itself. The DateTime class is broken, and starting with PHP 7.4 some properties are not shown by the reflection. See https://3v4l.org/joLur

<?php

$date = new DateTime();
$reflection = new ReflectionObject($date);
$props = [];

foreach ($reflection->getProperties() as $p) {
    $props[] = $p->getName();
}

var_dump($props);

So we never set the date, timezone and timezone_type properties because we cannot see them using reflection, resulting your error:

PHP Notice:  serialize(): "date" returned as member variable from __sleep() but does not exist in /mnt/c/Users/PhpstormProjects/closure-carbon-issue/vendor/opis/closure/src/SerializableClosure.php on line 155
PHP Notice:  serialize(): "timezone_type" returned as member variable from __sleep() but does not exist in /mnt/c/Users/PhpstormProjects/closure-carbon-issue/vendor/opis/closure/src/SerializableClosure.php on line 155
PHP Notice:  serialize(): "timezone" returned as member variable from __sleep() but does not exist in /mnt/c/Users/PhpstormProjects/closure-carbon-issue/vendor/opis/closure/src/SerializableClosure.php on line 155
PHP Fatal error:  Uncaught Error: Invalid serialization data for DateTime object in /mnt/c/Users/PhpstormProjects/closure-carbon-issue/vendor/nesbot/carbon/src/Carbon/Traits/Serialization.php:131
dercoder commented 4 years ago

I understand. The utput of PHP 8 is the same like PHP 7.4

When you serialize it, the properties are in the string:

var_dump(serialize(new DateTime()));

# string(128) "O:8:"DateTime":3:{s:4:"date";s:26:"2020-08-26 01:11:27.025541";s:13:"timezone_type";i:3;s:8:"timezone";s:16:"Europe/Amsterdam";}"

Do you got any ideas? Workaround?

dercoder commented 4 years ago

I found also this: https://bugs.php.net/bug.php?id=79041

didix16 commented 3 years ago

Hi there, is any workarround about this? I'm trying to store data inside a cache to improve laravel page speed but I cannot due serialize(): "date" returned as member variable from __sleep() but does not exist problem.

Thanks in advance