From 9d67308444c316788be6b5dff2c7493ea9cc1408 Mon Sep 17 00:00:00 2001 From: webimpress Date: Wed, 16 Oct 2019 10:15:32 +0100 Subject: [PATCH 1/2] Fix (un)serialization for Reflection* objects - PHP 7.4 Fixes #29 --- src/Reflection/AbstractFunction.php | 31 +++++++++++++++++++++++-- src/Reflection/ReflectionClass.php | 17 +++++++++++++- src/Reflection/ReflectionMethod.php | 3 ++- src/Reflection/ReflectionParameter.php | 32 ++++++++++++++++++++++++++ 4 files changed, 79 insertions(+), 4 deletions(-) diff --git a/src/Reflection/AbstractFunction.php b/src/Reflection/AbstractFunction.php index f9adfc2e..2c2bcfa7 100644 --- a/src/Reflection/AbstractFunction.php +++ b/src/Reflection/AbstractFunction.php @@ -51,6 +51,12 @@ abstract class AbstractFunction */ protected $class; + /** + * Function name (needed for serialization) + * @var string + */ + protected $name; + /** * Function/method description * @var string @@ -109,6 +115,8 @@ public function __construct(ReflectionFunctionAbstract $r, $namespace = null, $a $this->class = $r->getDeclaringClass()->getName(); } + $this->name = $r->getName(); + // Perform some introspection $this->reflect(); } @@ -438,6 +446,25 @@ public function getInvokeArguments() return $this->argv; } + /** + * @return string[] + */ + public function __sleep() + { + $serializable = []; + foreach ($this as $name => $value) { + if ($value instanceof PhpReflectionFunction + || $value instanceof PhpReflectionMethod + ) { + continue; + } + + $serializable[] = $name; + } + + return $serializable; + } + /** * Wakeup from serialization * @@ -450,9 +477,9 @@ public function __wakeup() { if ($this->reflection instanceof PhpReflectionMethod) { $class = new PhpReflectionClass($this->class); - $this->reflection = new PhpReflectionMethod($class->newInstance(), $this->getName()); + $this->reflection = new PhpReflectionMethod($class->newInstance(), $this->name); } else { - $this->reflection = new PhpReflectionFunction($this->getName()); + $this->reflection = new PhpReflectionFunction($this->name); } } } diff --git a/src/Reflection/ReflectionClass.php b/src/Reflection/ReflectionClass.php index 02027965..c6cae995 100644 --- a/src/Reflection/ReflectionClass.php +++ b/src/Reflection/ReflectionClass.php @@ -42,6 +42,12 @@ class ReflectionClass */ protected $reflection; + /** + * Reflection class name (needed for serialization) + * @var string + */ + protected $name; + /** * Constructor * @@ -55,6 +61,7 @@ class ReflectionClass public function __construct(PhpReflectionClass $reflection, $namespace = null, $argv = false) { $this->reflection = $reflection; + $this->name = $reflection->getName(); $this->setNamespace($namespace); foreach ($reflection->getMethods() as $method) { @@ -171,6 +178,14 @@ public function setNamespace($namespace) */ public function __wakeup() { - $this->reflection = new PhpReflectionClass($this->getName()); + $this->reflection = new PhpReflectionClass($this->name); + } + + /** + * @return string[] + */ + public function __sleep() + { + return ['config', 'methods', 'namespace', 'name']; } } diff --git a/src/Reflection/ReflectionMethod.php b/src/Reflection/ReflectionMethod.php index 09a6857c..0b4e9483 100644 --- a/src/Reflection/ReflectionMethod.php +++ b/src/Reflection/ReflectionMethod.php @@ -58,6 +58,7 @@ public function __construct(ReflectionClass $class, \ReflectionMethod $r, $names // If method call, need to store some info on the class $this->class = $class->getName(); + $this->name = $r->getName(); // Perform some introspection $this->reflect(); @@ -88,7 +89,7 @@ public function __wakeup() $this->getNamespace(), $this->getInvokeArguments() ); - $this->reflection = new \ReflectionMethod($this->classReflection->getName(), $this->getName()); + $this->reflection = new \ReflectionMethod($this->classReflection->getName(), $this->name); } /** diff --git a/src/Reflection/ReflectionParameter.php b/src/Reflection/ReflectionParameter.php index 94fa9a1e..5bcec7be 100644 --- a/src/Reflection/ReflectionParameter.php +++ b/src/Reflection/ReflectionParameter.php @@ -37,6 +37,18 @@ class ReflectionParameter */ protected $description; + /** + * Parameter name (needed for serialization) + * @var string + */ + protected $name; + + /** + * Declaring function name (needed for serialization) + * @var string + */ + protected $functionName; + /** * Constructor * @@ -47,6 +59,13 @@ class ReflectionParameter public function __construct(\ReflectionParameter $r, $type = 'mixed', $description = '') { $this->reflection = $r; + + // Store parameters needed for (un)serialization + $this->name = $r->getName(); + $this->functionName = $r->getDeclaringClass() + ? [$r->getDeclaringClass()->getName(), $r->getDeclaringFunction()->getName()] + : $r->getDeclaringFunction()->getName(); + $this->setType($type); $this->setDescription($description); } @@ -140,4 +159,17 @@ public function getPosition() { return $this->position; } + + /** + * @return string[] + */ + public function __sleep() + { + return ['position', 'type', 'description', 'name', 'functionName']; + } + + public function __wakeup() + { + $this->reflection = new \ReflectionParameter($this->functionName, $this->name); + } } From 70eb7e61fd562414d574e6300bd5d3741ed8e2ab Mon Sep 17 00:00:00 2001 From: webimpress Date: Wed, 16 Oct 2019 10:36:14 +0100 Subject: [PATCH 2/2] Changes properties to protected from private private properties of abstract class cannot be serialized on PHP versions prior to 7.4. Changed these properties to protected so we don't need to do anything extra on unserialization. --- src/Reflection/AbstractFunction.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Reflection/AbstractFunction.php b/src/Reflection/AbstractFunction.php index 2c2bcfa7..a1f551f1 100644 --- a/src/Reflection/AbstractFunction.php +++ b/src/Reflection/AbstractFunction.php @@ -81,11 +81,11 @@ abstract class AbstractFunction */ protected $docComment = ''; - private $return; - private $returnDesc; - private $paramDesc; - private $sigParams; - private $sigParamsDepth; + protected $return; + protected $returnDesc; + protected $paramDesc; + protected $sigParams; + protected $sigParamsDepth; /** * Constructor