Skip to content

Instantly share code, notes, and snippets.

@diloabininyeri
Created April 14, 2024 04:31
Show Gist options
  • Save diloabininyeri/038bb751d32fd2147cbcca7644c12e77 to your computer and use it in GitHub Desktop.
Save diloabininyeri/038bb751d32fd2147cbcca7644c12e77 to your computer and use it in GitHub Desktop.
serialize a closure in php
<?php
class ReflectionClosure extends ReflectionFunction
{
const string REGEX_PATTERN = '/function\s*\(\s*(.*?)\s*\)\s*(?:use\s*\(([^)]*)\)\s*)?{\s*(.*?)\s*}/s';
public function getCode(): string
{
$startLine = $this->getStartLine();
$endLine = $this->getEndLine();
$code = implode("\n", array_slice(file($this->getFileName()), $startLine - 1, $endLine + 1));
preg_match(self::REGEX_PATTERN, $code, $matches);
return $matches[0];
}
}
class SerializeClosure
{
private string $code;
private array $usesVariable;
public function __construct(Closure $closure)
{
$reflectionClosure = new ReflectionClosure($closure);
$this->code = $reflectionClosure->getCode();
$this->usesVariable = $reflectionClosure->getClosureUsedVariables();
}
public function __serialize(): array
{
return [
'code' => $this->code,
'use' => $this->usesVariable
];
}
public function __unserialize(array $data): void
{
$this->code = $data['code'];
$this->usesVariable = $data['use'];
}
public function getClosure(): Closure
{
extract($this->usesVariable);
return eval("return $this->code;");
}
}
$name = 'Dilo surucu';
$serializeClosure = new SerializeClosure(
function () use ($name) {
return $name;
});
$serialize = serialize($serializeClosure);
/**
* @var $unserialize SerializeClosure
*/
$unserialize = unserialize($serialize, ['allowed_classes' => true]);
$closure = $unserialize->getClosure();
echo $closure();//Dilo surucu
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment