Файловый менеджер - Редактировать - /home/tuudkjt/globeasy/wp-includes/ID3/laravel.tar
Назад
serializable-closure/README.md 0000777 00000005517 15251306123 0012160 0 ustar 00 # Serializable Closure <a href="https://github.com/laravel/serializable-closure/actions"> <img src="https://github.com/laravel/serializable-closure/workflows/tests/badge.svg" alt="Build Status"> </a> <a href="https://packagist.org/packages/laravel/serializable-closure"> <img src="https://img.shields.io/packagist/dt/laravel/serializable-closure" alt="Total Downloads"> </a> <a href="https://packagist.org/packages/laravel/serializable-closure"> <img src="https://img.shields.io/packagist/v/laravel/serializable-closure" alt="Latest Stable Version"> </a> <a href="https://packagist.org/packages/laravel/serializable-closure"> <img src="https://img.shields.io/packagist/l/laravel/serializable-closure" alt="License"> </a> ## Introduction > This project is a fork of the excellent [opis/closure: 3.x](https://github.com/opis/closure) package. At Laravel, we decided to fork this package as the upcoming version [4.x](https://github.com/opis/closure) is a complete rewrite on top of the [FFI extension](https://www.php.net/manual/en/book.ffi.php). As Laravel is a web framework, and FFI is not enabled by default in web requests, this fork allows us to keep using the `3.x` series while adding support for new PHP versions. Laravel Serializable Closure provides an easy and secure way to **serialize closures in PHP**. ## Official Documentation ### Installation > **Requires [PHP 7.4+](https://php.net/releases/)** First, install Laravel Serializable Closure via the [Composer](https://getcomposer.org/) package manager: ```bash composer require laravel/serializable-closure ``` ### Usage You may serialize a closure this way: ```php use Laravel\SerializableClosure\SerializableClosure; $closure = fn () => 'james'; // Recommended SerializableClosure::setSecretKey('secret'); $serialized = serialize(new SerializableClosure($closure)); $closure = unserialize($serialized)->getClosure(); echo $closure(); // james; ``` ### Caveats * Anonymous classes cannot be created within closures. * Attributes cannot be used within closures. * Serializing closures on REPL environments like Laravel Tinker is not supported. * Serializing closures that reference objects with readonly properties is not supported. ## Contributing Thank you for considering contributing to Serializable Closure! The contribution guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions). ## Code of Conduct In order to ensure that the Laravel community is welcoming to all, please review and abide by the [Code of Conduct](https://laravel.com/docs/contributions#code-of-conduct). ## Security Vulnerabilities Please review [our security policy](https://github.com/laravel/serializable-closure/security/policy) on how to report security vulnerabilities. ## License Serializable Closure is open-sourced software licensed under the [MIT license](LICENSE.md). serializable-closure/LICENSE.md 0000777 00000002063 15251306123 0012276 0 ustar 00 The MIT License (MIT) Copyright (c) Taylor Otwell Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. serializable-closure/composer.json 0000777 00000002666 15251306123 0013425 0 ustar 00 { "name": "laravel\/serializable-closure", "description": "Laravel Serializable Closure provides an easy and secure way to serialize closures in PHP.", "keywords": [ "laravel", "Serializable", "closure" ], "license": "MIT", "support": { "issues": "https:\/\/github.com\/laravel\/serializable-closure\/issues", "source": "https:\/\/github.com\/laravel\/serializable-closure" }, "authors": [ { "name": "Taylor Otwell", "email": "taylor@laravel.com" }, { "name": "Nuno Maduro", "email": "nuno@laravel.com" } ], "require": { "php": "^7.3|^8.0" }, "require-dev": { "illuminate\/support": "^8.0|^9.0|^10.0|^11.0", "nesbot\/carbon": "^2.61|^3.0", "pestphp\/pest": "^1.21.3", "phpstan\/phpstan": "^1.8.2", "symfony\/var-dumper": "^5.4.11|^6.2.0|^7.0.0" }, "autoload": { "psr-4": { "Rvx\\Laravel\\SerializableClosure\\": "src\/" } }, "autoload-dev": { "psr-4": { "Rvx\\Tests\\": "tests\/" } }, "extra": { "branch-alias": { "dev-master": "1.x-dev" } }, "config": { "sort-packages": true, "allow-plugins": { "pestphp\/pest-plugin": true } }, "minimum-stability": "dev", "prefer-stable": true } serializable-closure/src/Support/ClosureScope.php 0000777 00000000574 15251306123 0016261 0 ustar 00 <?php namespace Rvx\Laravel\SerializableClosure\Support; use SplObjectStorage; class ClosureScope extends SplObjectStorage { /** * The number of serializations in current scope. * * @var int */ public $serializations = 0; /** * The number of closures that have to be serialized. * * @var int */ public $toSerialize = 0; } serializable-closure/src/Support/ReflectionClosure.php 0000777 00000130160 15251306123 0017275 0 ustar 00 <?php namespace Rvx\Laravel\SerializableClosure\Support; \defined('T_NAME_QUALIFIED') || \define('T_NAME_QUALIFIED', -4); \defined('T_NAME_FULLY_QUALIFIED') || \define('T_NAME_FULLY_QUALIFIED', -5); \defined('T_FN') || \define('T_FN', -6); \defined('T_NULLSAFE_OBJECT_OPERATOR') || \define('T_NULLSAFE_OBJECT_OPERATOR', -7); use Closure; use ReflectionFunction; class ReflectionClosure extends ReflectionFunction { protected $code; protected $tokens; protected $hashedName; protected $useVariables; protected $isStaticClosure; protected $isScopeRequired; protected $isBindingRequired; protected $isShortClosure; protected static $files = []; protected static $classes = []; protected static $functions = []; protected static $constants = []; protected static $structures = []; /** * Creates a new reflection closure instance. * * @param \Closure $closure * @param string|null $code * @return void */ public function __construct(Closure $closure, $code = null) { parent::__construct($closure); } /** * Checks if the closure is "static". * * @return bool */ public function isStatic() : bool { if ($this->isStaticClosure === null) { $this->isStaticClosure = \strtolower(\substr($this->getCode(), 0, 6)) === 'static'; } return $this->isStaticClosure; } /** * Checks if the closure is a "short closure". * * @return bool */ public function isShortClosure() { if ($this->isShortClosure === null) { $code = $this->getCode(); if ($this->isStatic()) { $code = \substr($code, 6); } $this->isShortClosure = \strtolower(\substr(\trim($code), 0, 2)) === 'fn'; } return $this->isShortClosure; } /** * Get the closure's code. * * @return string */ public function getCode() { if ($this->code !== null) { return $this->code; } $fileName = $this->getFileName(); $line = $this->getStartLine() - 1; $className = null; if (null !== ($className = $this->getClosureScopeClass())) { $className = '\\' . \trim($className->getName(), '\\'); } $builtin_types = self::getBuiltinTypes(); $class_keywords = ['self', 'static', 'parent']; $ns = $this->getClosureNamespaceName(); $nsf = $ns == '' ? '' : ($ns[0] == '\\' ? $ns : '\\' . $ns); $_file = \var_export($fileName, \true); $_dir = \var_export(\dirname($fileName), \true); $_namespace = \var_export($ns, \true); $_class = \var_export(\trim($className ?: '', '\\'), \true); $_function = $ns . ($ns == '' ? '' : '\\') . '{closure}'; $_method = ($className == '' ? '' : \trim($className, '\\') . '::') . $_function; $_function = \var_export($_function, \true); $_method = \var_export($_method, \true); $_trait = null; $tokens = $this->getTokens(); $state = $lastState = 'start'; $inside_structure = \false; $isFirstClassCallable = \false; $isShortClosure = \false; $inside_structure_mark = 0; $open = 0; $code = ''; $id_start = $id_start_ci = $id_name = $context = ''; $classes = $functions = $constants = null; $use = []; $lineAdd = 0; $isUsingScope = \false; $isUsingThisObject = \false; for ($i = 0, $l = \count($tokens); $i < $l; $i++) { $token = $tokens[$i]; switch ($state) { case 'start': if ($token[0] === \T_FUNCTION || $token[0] === \T_STATIC) { $code .= $token[1]; $state = $token[0] === \T_FUNCTION ? 'function' : 'static'; } elseif ($token[0] === \T_FN) { $isShortClosure = \true; $code .= $token[1]; $state = 'closure_args'; } elseif ($token[0] === \T_PUBLIC || $token[0] === \T_PROTECTED || $token[0] === \T_PRIVATE) { $code = ''; $isFirstClassCallable = \true; } break; case 'static': if ($token[0] === \T_WHITESPACE || $token[0] === \T_COMMENT || $token[0] === \T_FUNCTION) { $code .= $token[1]; if ($token[0] === \T_FUNCTION) { $state = 'function'; } } elseif ($token[0] === \T_FN) { $isShortClosure = \true; $code .= $token[1]; $state = 'closure_args'; } else { $code = ''; $state = 'start'; } break; case 'function': switch ($token[0]) { case \T_STRING: if ($isFirstClassCallable) { $state = 'closure_args'; break; } $code = ''; $state = 'named_function'; break; case '(': $code .= '('; $state = 'closure_args'; break; default: $code .= \is_array($token) ? $token[1] : $token; } break; case 'named_function': if ($token[0] === \T_FUNCTION || $token[0] === \T_STATIC) { $code = $token[1]; $state = $token[0] === \T_FUNCTION ? 'function' : 'static'; } elseif ($token[0] === \T_FN) { $isShortClosure = \true; $code .= $token[1]; $state = 'closure_args'; } break; case 'closure_args': switch ($token[0]) { case \T_NAME_QUALIFIED: [$id_start, $id_start_ci, $id_name] = $this->parseNameQualified($token[1]); $context = 'args'; $state = 'id_name'; $lastState = 'closure_args'; break; case \T_NS_SEPARATOR: case \T_STRING: $id_start = $token[1]; $id_start_ci = \strtolower($id_start); $id_name = ''; $context = 'args'; $state = 'id_name'; $lastState = 'closure_args'; break; case \T_USE: $code .= $token[1]; $state = 'use'; break; case \T_DOUBLE_ARROW: $code .= $token[1]; if ($isShortClosure) { $state = 'closure'; } break; case ':': $code .= ':'; $state = 'return'; break; case '{': $code .= '{'; $state = 'closure'; $open++; break; default: $code .= \is_array($token) ? $token[1] : $token; } break; case 'use': switch ($token[0]) { case \T_VARIABLE: $use[] = \substr($token[1], 1); $code .= $token[1]; break; case '{': $code .= '{'; $state = 'closure'; $open++; break; case ':': $code .= ':'; $state = 'return'; break; default: $code .= \is_array($token) ? $token[1] : $token; break; } break; case 'return': switch ($token[0]) { case \T_WHITESPACE: case \T_COMMENT: case \T_DOC_COMMENT: $code .= $token[1]; break; case \T_NS_SEPARATOR: case \T_STRING: $id_start = $token[1]; $id_start_ci = \strtolower($id_start); $id_name = ''; $context = 'return_type'; $state = 'id_name'; $lastState = 'return'; break 2; case \T_NAME_QUALIFIED: [$id_start, $id_start_ci, $id_name] = $this->parseNameQualified($token[1]); $context = 'return_type'; $state = 'id_name'; $lastState = 'return'; break 2; case \T_DOUBLE_ARROW: $code .= $token[1]; if ($isShortClosure) { $state = 'closure'; } break; case '{': $code .= '{'; $state = 'closure'; $open++; break; default: $code .= \is_array($token) ? $token[1] : $token; break; } break; case 'closure': switch ($token[0]) { case \T_CURLY_OPEN: case \T_DOLLAR_OPEN_CURLY_BRACES: case '{': $code .= \is_array($token) ? $token[1] : $token; $open++; break; case '}': $code .= '}'; if (--$open === 0 && !$isShortClosure) { break 3; } elseif ($inside_structure) { $inside_structure = !($open === $inside_structure_mark); } break; case '(': case '[': $code .= $token[0]; if ($isShortClosure) { $open++; } break; case ')': case ']': if ($isShortClosure) { if ($open === 0) { break 3; } $open--; } $code .= $token[0]; break; case ',': case ';': if ($isShortClosure && $open === 0) { break 3; } $code .= $token[0]; break; case \T_LINE: $code .= $token[2] - $line + $lineAdd; break; case \T_FILE: $code .= $_file; break; case \T_DIR: $code .= $_dir; break; case \T_NS_C: $code .= $_namespace; break; case \T_CLASS_C: $code .= $inside_structure ? $token[1] : $_class; break; case \T_FUNC_C: $code .= $inside_structure ? $token[1] : $_function; break; case \T_METHOD_C: $code .= $inside_structure ? $token[1] : $_method; break; case \T_COMMENT: if (\substr($token[1], 0, 8) === '#trackme') { $timestamp = \time(); $code .= '/**' . \PHP_EOL; $code .= '* Date : ' . \date(\DATE_W3C, $timestamp) . \PHP_EOL; $code .= '* Timestamp : ' . $timestamp . \PHP_EOL; $code .= '* Line : ' . ($line + 1) . \PHP_EOL; $code .= '* File : ' . $_file . \PHP_EOL . '*/' . \PHP_EOL; $lineAdd += 5; } else { $code .= $token[1]; } break; case \T_VARIABLE: if ($token[1] == '$this' && !$inside_structure) { $isUsingThisObject = \true; } $code .= $token[1]; break; case \T_STATIC: case \T_NS_SEPARATOR: case \T_STRING: $id_start = $token[1]; $id_start_ci = \strtolower($id_start); $id_name = ''; $context = 'root'; $state = 'id_name'; $lastState = 'closure'; break 2; case \T_NAME_QUALIFIED: [$id_start, $id_start_ci, $id_name] = $this->parseNameQualified($token[1]); $context = 'root'; $state = 'id_name'; $lastState = 'closure'; break 2; case \T_NEW: $code .= $token[1]; $context = 'new'; $state = 'id_start'; $lastState = 'closure'; break 2; case \T_USE: $code .= $token[1]; $context = 'use'; $state = 'id_start'; $lastState = 'closure'; break; case \T_INSTANCEOF: case \T_INSTEADOF: $code .= $token[1]; $context = 'instanceof'; $state = 'id_start'; $lastState = 'closure'; break; case \T_OBJECT_OPERATOR: case \T_NULLSAFE_OBJECT_OPERATOR: case \T_DOUBLE_COLON: $code .= $token[1]; $lastState = 'closure'; $state = 'ignore_next'; break; case \T_FUNCTION: $code .= $token[1]; $state = 'closure_args'; if (!$inside_structure) { $inside_structure = \true; $inside_structure_mark = $open; } break; case \T_TRAIT_C: if ($_trait === null) { $startLine = $this->getStartLine(); $endLine = $this->getEndLine(); $structures = $this->getStructures(); $_trait = ''; foreach ($structures as &$struct) { if ($struct['type'] === 'trait' && $struct['start'] <= $startLine && $struct['end'] >= $endLine) { $_trait = ($ns == '' ? '' : $ns . '\\') . $struct['name']; break; } } $_trait = \var_export($_trait, \true); } $code .= $_trait; break; default: $code .= \is_array($token) ? $token[1] : $token; } break; case 'ignore_next': switch ($token[0]) { case \T_WHITESPACE: case \T_COMMENT: case \T_DOC_COMMENT: $code .= $token[1]; break; case \T_CLASS: case \T_NEW: case \T_STATIC: case \T_VARIABLE: case \T_STRING: case \T_CLASS_C: case \T_FILE: case \T_DIR: case \T_METHOD_C: case \T_FUNC_C: case \T_FUNCTION: case \T_INSTANCEOF: case \T_LINE: case \T_NS_C: case \T_TRAIT_C: case \T_USE: $code .= $token[1]; $state = $lastState; break; default: $state = $lastState; $i--; } break; case 'id_start': switch ($token[0]) { case \T_WHITESPACE: case \T_COMMENT: case \T_DOC_COMMENT: $code .= $token[1]; break; case \T_NS_SEPARATOR: case \T_NAME_FULLY_QUALIFIED: case \T_STRING: case \T_STATIC: $id_start = $token[1]; $id_start_ci = \strtolower($id_start); $id_name = ''; $state = 'id_name'; break 2; case \T_NAME_QUALIFIED: [$id_start, $id_start_ci, $id_name] = $this->parseNameQualified($token[1]); $state = 'id_name'; break 2; case \T_VARIABLE: $code .= $token[1]; $state = $lastState; break; case \T_CLASS: $code .= $token[1]; $state = 'anonymous'; break; default: $i--; //reprocess last $state = 'id_name'; } break; case 'id_name': switch ($token[0]) { case $token[0] === ':' && $context !== 'instanceof': if ($lastState === 'closure' && $context === 'root') { $state = 'closure'; $code .= $id_start . $token; } break; case \T_NAME_QUALIFIED: case \T_NS_SEPARATOR: case \T_STRING: case \T_WHITESPACE: case \T_COMMENT: case \T_DOC_COMMENT: $id_name .= $token[1]; break; case '(': if ($isShortClosure) { $open++; } if ($context === 'new' || \false !== \strpos($id_name, '\\')) { if ($id_start_ci === 'self' || $id_start_ci === 'static') { if (!$inside_structure) { $isUsingScope = \true; } } elseif ($id_start !== '\\' && !\in_array($id_start_ci, $class_keywords)) { if ($classes === null) { $classes = $this->getClasses(); } if (isset($classes[$id_start_ci])) { $id_start = $classes[$id_start_ci]; } if ($id_start[0] !== '\\') { $id_start = $nsf . '\\' . $id_start; } } } else { if ($id_start !== '\\') { if ($functions === null) { $functions = $this->getFunctions(); } if (isset($functions[$id_start_ci])) { $id_start = $functions[$id_start_ci]; } elseif ($nsf !== '\\' && \function_exists($nsf . '\\' . $id_start)) { $id_start = $nsf . '\\' . $id_start; // Cache it to functions array $functions[$id_start_ci] = $id_start; } } } $code .= $id_start . $id_name . '('; $state = $lastState; break; case \T_VARIABLE: case \T_DOUBLE_COLON: if ($id_start !== '\\') { if ($id_start_ci === 'self' || $id_start_ci === 'parent') { if (!$inside_structure) { $isUsingScope = \true; } } elseif ($id_start_ci === 'static') { if (!$inside_structure) { $isUsingScope = $token[0] === \T_DOUBLE_COLON; } } elseif (!(\PHP_MAJOR_VERSION >= 7 && \in_array($id_start_ci, $builtin_types))) { if ($classes === null) { $classes = $this->getClasses(); } if (isset($classes[$id_start_ci])) { $id_start = $classes[$id_start_ci]; } if ($id_start[0] !== '\\') { $id_start = $nsf . '\\' . $id_start; } } } $code .= $id_start . $id_name . $token[1]; $state = $token[0] === \T_DOUBLE_COLON ? 'ignore_next' : $lastState; break; default: if ($id_start !== '\\' && !\defined($id_start)) { if ($constants === null) { $constants = $this->getConstants(); } if (isset($constants[$id_start])) { $id_start = $constants[$id_start]; } elseif ($context === 'new') { if (\in_array($id_start_ci, $class_keywords)) { if (!$inside_structure) { $isUsingScope = \true; } } else { if ($classes === null) { $classes = $this->getClasses(); } if (isset($classes[$id_start_ci])) { $id_start = $classes[$id_start_ci]; } if ($id_start[0] !== '\\') { $id_start = $nsf . '\\' . $id_start; } } } elseif ($context === 'use' || $context === 'instanceof' || $context === 'args' || $context === 'return_type' || $context === 'extends' || $context === 'root') { if (\in_array($id_start_ci, $class_keywords)) { if (!$inside_structure && !$id_start_ci === 'static') { $isUsingScope = \true; } } elseif (!(\PHP_MAJOR_VERSION >= 7 && \in_array($id_start_ci, $builtin_types))) { if ($classes === null) { $classes = $this->getClasses(); } if (isset($classes[$id_start_ci])) { $id_start = $classes[$id_start_ci]; } if ($id_start[0] !== '\\') { $id_start = $nsf . '\\' . $id_start; } } } } $code .= $id_start . $id_name; $state = $lastState; $i--; } break; case 'anonymous': switch ($token[0]) { case \T_NAME_QUALIFIED: [$id_start, $id_start_ci, $id_name] = $this->parseNameQualified($token[1]); $state = 'id_name'; $lastState = 'anonymous'; break 2; case \T_NS_SEPARATOR: case \T_STRING: $id_start = $token[1]; $id_start_ci = \strtolower($id_start); $id_name = ''; $state = 'id_name'; $context = 'extends'; $lastState = 'anonymous'; break; case '{': $state = 'closure'; if (!$inside_structure) { $inside_structure = \true; $inside_structure_mark = $open; } $i--; break; default: $code .= \is_array($token) ? $token[1] : $token; } break; } } if ($isShortClosure) { $this->useVariables = $this->getStaticVariables(); } else { $this->useVariables = empty($use) ? $use : \array_intersect_key($this->getStaticVariables(), \array_flip($use)); } $this->isShortClosure = $isShortClosure; $this->isBindingRequired = $isUsingThisObject; $this->isScopeRequired = $isUsingScope; if (\PHP_VERSION_ID >= 80100) { $attributesCode = \array_map(function ($attribute) { $arguments = $attribute->getArguments(); $name = $attribute->getName(); $arguments = \implode(', ', \array_map(function ($argument, $key) { $argument = \sprintf("'%s'", \str_replace("'", "\\'", $argument)); if (\is_string($key)) { $argument = \sprintf('%s: %s', $key, $argument); } return $argument; }, $arguments, \array_keys($arguments))); return "#[{$name}({$arguments})]"; }, $this->getAttributes()); if (!empty($attributesCode)) { $code = \implode("\n", \array_merge($attributesCode, [$code])); } } $this->code = $code; return $this->code; } /** * Get PHP native built in types. * * @return array */ protected static function getBuiltinTypes() { // PHP 8.1 if (\PHP_VERSION_ID >= 80100) { return ['array', 'callable', 'string', 'int', 'bool', 'float', 'iterable', 'void', 'object', 'mixed', 'false', 'null', 'never']; } // PHP 8 if (\PHP_MAJOR_VERSION === 8) { return ['array', 'callable', 'string', 'int', 'bool', 'float', 'iterable', 'void', 'object', 'mixed', 'false', 'null']; } // PHP 7 switch (\PHP_MINOR_VERSION) { case 0: return ['array', 'callable', 'string', 'int', 'bool', 'float']; case 1: return ['array', 'callable', 'string', 'int', 'bool', 'float', 'iterable', 'void']; default: return ['array', 'callable', 'string', 'int', 'bool', 'float', 'iterable', 'void', 'object']; } } /** * Gets the use variables by the closure. * * @return array */ public function getUseVariables() { if ($this->useVariables !== null) { return $this->useVariables; } $tokens = $this->getTokens(); $use = []; $state = 'start'; foreach ($tokens as &$token) { $is_array = \is_array($token); switch ($state) { case 'start': if ($is_array && $token[0] === \T_USE) { $state = 'use'; } break; case 'use': if ($is_array) { if ($token[0] === \T_VARIABLE) { $use[] = \substr($token[1], 1); } } elseif ($token == ')') { break 2; } break; } } $this->useVariables = empty($use) ? $use : \array_intersect_key($this->getStaticVariables(), \array_flip($use)); return $this->useVariables; } /** * Checks if binding is required. * * @return bool */ public function isBindingRequired() { if ($this->isBindingRequired === null) { $this->getCode(); } return $this->isBindingRequired; } /** * Checks if access to the scope is required. * * @return bool */ public function isScopeRequired() { if ($this->isScopeRequired === null) { $this->getCode(); } return $this->isScopeRequired; } /** * The hash of the current file name. * * @return string */ protected function getHashedFileName() { if ($this->hashedName === null) { $this->hashedName = \sha1($this->getFileName()); } return $this->hashedName; } /** * Get the file tokens. * * @return array */ protected function getFileTokens() { $key = $this->getHashedFileName(); if (!isset(static::$files[$key])) { static::$files[$key] = \token_get_all(\file_get_contents($this->getFileName())); } return static::$files[$key]; } /** * Get the tokens. * * @return array */ protected function getTokens() { if ($this->tokens === null) { $tokens = $this->getFileTokens(); $startLine = $this->getStartLine(); $endLine = $this->getEndLine(); $results = []; $start = \false; foreach ($tokens as &$token) { if (!\is_array($token)) { if ($start) { $results[] = $token; } continue; } $line = $token[2]; if ($line <= $endLine) { if ($line >= $startLine) { $start = \true; $results[] = $token; } continue; } break; } $this->tokens = $results; } return $this->tokens; } /** * Get the classes. * * @return array */ protected function getClasses() { $key = $this->getHashedFileName(); if (!isset(static::$classes[$key])) { $this->fetchItems(); } return static::$classes[$key]; } /** * Get the functions. * * @return array */ protected function getFunctions() { $key = $this->getHashedFileName(); if (!isset(static::$functions[$key])) { $this->fetchItems(); } return static::$functions[$key]; } /** * Gets the constants. * * @return array */ protected function getConstants() { $key = $this->getHashedFileName(); if (!isset(static::$constants[$key])) { $this->fetchItems(); } return static::$constants[$key]; } /** * Get the structures. * * @return array */ protected function getStructures() { $key = $this->getHashedFileName(); if (!isset(static::$structures[$key])) { $this->fetchItems(); } return static::$structures[$key]; } /** * Fetch the items. * * @return void. */ protected function fetchItems() { $key = $this->getHashedFileName(); $classes = []; $functions = []; $constants = []; $structures = []; $tokens = $this->getFileTokens(); $open = 0; $state = 'start'; $lastState = ''; $prefix = ''; $name = ''; $alias = ''; $isFunc = $isConst = \false; $startLine = $endLine = 0; $structType = $structName = ''; $structIgnore = \false; foreach ($tokens as $token) { switch ($state) { case 'start': switch ($token[0]) { case \T_CLASS: case \T_INTERFACE: case \T_TRAIT: $state = 'before_structure'; $startLine = $token[2]; $structType = $token[0] == \T_CLASS ? 'class' : ($token[0] == \T_INTERFACE ? 'interface' : 'trait'); break; case \T_USE: $state = 'use'; $prefix = $name = $alias = ''; $isFunc = $isConst = \false; break; case \T_FUNCTION: $state = 'structure'; $structIgnore = \true; break; case \T_NEW: $state = 'new'; break; case \T_OBJECT_OPERATOR: case \T_DOUBLE_COLON: $state = 'invoke'; break; } break; case 'use': switch ($token[0]) { case \T_FUNCTION: $isFunc = \true; break; case \T_CONST: $isConst = \true; break; case \T_NS_SEPARATOR: $name .= $token[1]; break; case \T_STRING: $name .= $token[1]; $alias = $token[1]; break; case \T_NAME_QUALIFIED: $name .= $token[1]; $pieces = \explode('\\', $token[1]); $alias = \end($pieces); break; case \T_AS: $lastState = 'use'; $state = 'alias'; break; case '{': $prefix = $name; $name = $alias = ''; $state = 'use-group'; break; case ',': case ';': if ($name === '' || $name[0] !== '\\') { $name = '\\' . $name; } if ($alias !== '') { if ($isFunc) { $functions[\strtolower($alias)] = $name; } elseif ($isConst) { $constants[$alias] = $name; } else { $classes[\strtolower($alias)] = $name; } } $name = $alias = ''; $state = $token === ';' ? 'start' : 'use'; break; } break; case 'use-group': switch ($token[0]) { case \T_NS_SEPARATOR: $name .= $token[1]; break; case \T_NAME_QUALIFIED: $name .= $token[1]; $pieces = \explode('\\', $token[1]); $alias = \end($pieces); break; case \T_STRING: $name .= $token[1]; $alias = $token[1]; break; case \T_AS: $lastState = 'use-group'; $state = 'alias'; break; case ',': case '}': if ($prefix === '' || $prefix[0] !== '\\') { $prefix = '\\' . $prefix; } if ($alias !== '') { if ($isFunc) { $functions[\strtolower($alias)] = $prefix . $name; } elseif ($isConst) { $constants[$alias] = $prefix . $name; } else { $classes[\strtolower($alias)] = $prefix . $name; } } $name = $alias = ''; $state = $token === '}' ? 'use' : 'use-group'; break; } break; case 'alias': if ($token[0] === \T_STRING) { $alias = $token[1]; $state = $lastState; } break; case 'new': switch ($token[0]) { case \T_WHITESPACE: case \T_COMMENT: case \T_DOC_COMMENT: break 2; case \T_CLASS: $state = 'structure'; $structIgnore = \true; break; default: $state = 'start'; } break; case 'invoke': switch ($token[0]) { case \T_WHITESPACE: case \T_COMMENT: case \T_DOC_COMMENT: break 2; default: $state = 'start'; } break; case 'before_structure': if ($token[0] == \T_STRING) { $structName = $token[1]; $state = 'structure'; } break; case 'structure': switch ($token[0]) { case '{': case \T_CURLY_OPEN: case \T_DOLLAR_OPEN_CURLY_BRACES: $open++; break; case '}': if (--$open == 0) { if (!$structIgnore) { $structures[] = ['type' => $structType, 'name' => $structName, 'start' => $startLine, 'end' => $endLine]; } $structIgnore = \false; $state = 'start'; } break; default: if (\is_array($token)) { $endLine = $token[2]; } } break; } } static::$classes[$key] = $classes; static::$functions[$key] = $functions; static::$constants[$key] = $constants; static::$structures[$key] = $structures; } /** * Returns the namespace associated to the closure. * * @return string */ protected function getClosureNamespaceName() { $ns = $this->getNamespaceName(); // First class callables... if ($this->getName() !== '{closure}' && empty($ns) && !\is_null($this->getClosureScopeClass())) { $ns = $this->getClosureScopeClass()->getNamespaceName(); } return $ns; } /** * Parse the given token. * * @param string $token * @return array */ protected function parseNameQualified($token) { $pieces = \explode('\\', $token); $id_start = \array_shift($pieces); $id_start_ci = \strtolower($id_start); $id_name = '\\' . \implode('\\', $pieces); return [$id_start, $id_start_ci, $id_name]; } } serializable-closure/src/Support/SelfReference.php 0000777 00000000605 15251306123 0016356 0 ustar 00 <?php namespace Rvx\Laravel\SerializableClosure\Support; class SelfReference { /** * The unique hash representing the object. * * @var string */ public $hash; /** * Creates a new self reference instance. * * @param string $hash * @return void */ public function __construct($hash) { $this->hash = $hash; } } serializable-closure/src/Support/ClosureStream.php 0000777 00000007012 15251306123 0016435 0 ustar 00 <?php namespace Rvx\Laravel\SerializableClosure\Support; #[\AllowDynamicProperties] class ClosureStream { /** * The stream protocol. */ const STREAM_PROTO = 'laravel-serializable-closure'; /** * Checks if this stream is registered. * * @var bool */ protected static $isRegistered = \false; /** * The stream content. * * @var string */ protected $content; /** * The stream content. * * @var int */ protected $length; /** * The stream pointer. * * @var int */ protected $pointer = 0; /** * Opens file or URL. * * @param string $path * @param string $mode * @param string $options * @param string|null $opened_path * @return bool */ public function stream_open($path, $mode, $options, &$opened_path) { $this->content = "<?php\nreturn " . \substr($path, \strlen(static::STREAM_PROTO . '://')) . ';'; $this->length = \strlen($this->content); return \true; } /** * Read from stream. * * @param int $count * @return string */ public function stream_read($count) { $value = \substr($this->content, $this->pointer, $count); $this->pointer += $count; return $value; } /** * Tests for end-of-file on a file pointer. * * @return bool */ public function stream_eof() { return $this->pointer >= $this->length; } /** * Change stream options. * * @param int $option * @param int $arg1 * @param int $arg2 * @return bool */ public function stream_set_option($option, $arg1, $arg2) { return \false; } /** * Retrieve information about a file resource. * * @return array|bool */ public function stream_stat() { $stat = \stat(__FILE__); // @phpstan-ignore-next-line $stat[7] = $stat['size'] = $this->length; return $stat; } /** * Retrieve information about a file. * * @param string $path * @param int $flags * @return array|bool */ public function url_stat($path, $flags) { $stat = \stat(__FILE__); // @phpstan-ignore-next-line $stat[7] = $stat['size'] = $this->length; return $stat; } /** * Seeks to specific location in a stream. * * @param int $offset * @param int $whence * @return bool */ public function stream_seek($offset, $whence = \SEEK_SET) { $crt = $this->pointer; switch ($whence) { case \SEEK_SET: $this->pointer = $offset; break; case \SEEK_CUR: $this->pointer += $offset; break; case \SEEK_END: $this->pointer = $this->length + $offset; break; } if ($this->pointer < 0 || $this->pointer >= $this->length) { $this->pointer = $crt; return \false; } return \true; } /** * Retrieve the current position of a stream. * * @return int */ public function stream_tell() { return $this->pointer; } /** * Registers the stream. * * @return void */ public static function register() { if (!static::$isRegistered) { static::$isRegistered = \stream_wrapper_register(static::STREAM_PROTO, __CLASS__); } } } serializable-closure/src/Signers/Hmac.php 0000777 00000002003 15251306123 0014446 0 ustar 00 <?php namespace Rvx\Laravel\SerializableClosure\Signers; use Rvx\Laravel\SerializableClosure\Contracts\Signer; class Hmac implements Signer { /** * The secret key. * * @var string */ protected $secret; /** * Creates a new signer instance. * * @param string $secret * @return void */ public function __construct($secret) { $this->secret = $secret; } /** * Sign the given serializable. * * @param string $serialized * @return array */ public function sign($serialized) { return ['serializable' => $serialized, 'hash' => \base64_encode(\hash_hmac('sha256', $serialized, $this->secret, \true))]; } /** * Verify the given signature. * * @param array $signature * @return bool */ public function verify($signature) { return \hash_equals(\base64_encode(\hash_hmac('sha256', $signature['serializable'], $this->secret, \true)), $signature['hash']); } } serializable-closure/src/Contracts/Signer.php 0000777 00000000607 15251306123 0015363 0 ustar 00 <?php namespace Rvx\Laravel\SerializableClosure\Contracts; interface Signer { /** * Sign the given serializable. * * @param string $serializable * @return array */ public function sign($serializable); /** * Verify the given signature. * * @param array $signature * @return bool */ public function verify($signature); } serializable-closure/src/Contracts/Serializable.php 0000777 00000000544 15251306123 0016542 0 ustar 00 <?php namespace Rvx\Laravel\SerializableClosure\Contracts; interface Serializable { /** * Resolve the closure with the given arguments. * * @return mixed */ public function __invoke(); /** * Gets the closure that got serialized/unserialized. * * @return \Closure */ public function getClosure(); } serializable-closure/src/Exceptions/MissingSecretKeyException.php 0000777 00000000616 15251306123 0021424 0 ustar 00 <?php namespace Rvx\Laravel\SerializableClosure\Exceptions; use Exception; class MissingSecretKeyException extends Exception { /** * Create a new exception instance. * * @param string $message * @return void */ public function __construct($message = 'No serializable closure secret key has been specified.') { parent::__construct($message); } } serializable-closure/src/Exceptions/PhpVersionNotSupportedException.php 0000777 00000000567 15251306123 0022665 0 ustar 00 <?php namespace Rvx\Laravel\SerializableClosure\Exceptions; use Exception; class PhpVersionNotSupportedException extends Exception { /** * Create a new exception instance. * * @param string $message * @return void */ public function __construct($message = 'PHP 7.3 is not supported.') { parent::__construct($message); } } serializable-closure/src/Exceptions/InvalidSignatureException.php 0000777 00000000654 15251306123 0021446 0 ustar 00 <?php namespace Rvx\Laravel\SerializableClosure\Exceptions; use Exception; class InvalidSignatureException extends Exception { /** * Create a new exception instance. * * @param string $message * @return void */ public function __construct($message = 'Your serialized closure might have been modified or it\'s unsafe to be unserialized.') { parent::__construct($message); } } serializable-closure/src/UnsignedSerializableClosure.php 0000777 00000003270 15251306123 0017633 0 ustar 00 <?php namespace Rvx\Laravel\SerializableClosure; use Closure; use Rvx\Laravel\SerializableClosure\Exceptions\PhpVersionNotSupportedException; class UnsignedSerializableClosure { /** * The closure's serializable. * * @var \Laravel\SerializableClosure\Contracts\Serializable */ protected $serializable; /** * Creates a new serializable closure instance. * * @param \Closure $closure * @return void */ public function __construct(Closure $closure) { if (\PHP_VERSION_ID < 70400) { throw new PhpVersionNotSupportedException(); } $this->serializable = new Serializers\Native($closure); } /** * Resolve the closure with the given arguments. * * @return mixed */ public function __invoke() { if (\PHP_VERSION_ID < 70400) { throw new PhpVersionNotSupportedException(); } return \call_user_func_array($this->serializable, \func_get_args()); } /** * Gets the closure. * * @return \Closure */ public function getClosure() { if (\PHP_VERSION_ID < 70400) { throw new PhpVersionNotSupportedException(); } return $this->serializable->getClosure(); } /** * Get the serializable representation of the closure. * * @return array */ public function __serialize() { return ['serializable' => $this->serializable]; } /** * Restore the closure after serialization. * * @param array $data * @return void */ public function __unserialize($data) { $this->serializable = $data['serializable']; } } serializable-closure/src/Serializers/Native.php 0000777 00000034114 15251306123 0015716 0 ustar 00 <?php namespace Rvx\Laravel\SerializableClosure\Serializers; use Closure; use DateTimeInterface; use Rvx\Laravel\SerializableClosure\Contracts\Serializable; use Rvx\Laravel\SerializableClosure\SerializableClosure; use Rvx\Laravel\SerializableClosure\Support\ClosureScope; use Rvx\Laravel\SerializableClosure\Support\ClosureStream; use Rvx\Laravel\SerializableClosure\Support\ReflectionClosure; use Rvx\Laravel\SerializableClosure\Support\SelfReference; use Rvx\Laravel\SerializableClosure\UnsignedSerializableClosure; use ReflectionObject; use UnitEnum; class Native implements Serializable { /** * Transform the use variables before serialization. * * @var \Closure|null */ public static $transformUseVariables; /** * Resolve the use variables after unserialization. * * @var \Closure|null */ public static $resolveUseVariables; /** * The closure to be serialized/unserialized. * * @var \Closure */ protected $closure; /** * The closure's reflection. * * @var \Laravel\SerializableClosure\Support\ReflectionClosure|null */ protected $reflector; /** * The closure's code. * * @var array|null */ protected $code; /** * The closure's reference. * * @var string */ protected $reference; /** * The closure's scope. * * @var \Laravel\SerializableClosure\Support\ClosureScope|null */ protected $scope; /** * The "key" that marks an array as recursive. */ const ARRAY_RECURSIVE_KEY = 'LARAVEL_SERIALIZABLE_RECURSIVE_KEY'; /** * Creates a new serializable closure instance. * * @param \Closure $closure * @return void */ public function __construct(Closure $closure) { $this->closure = $closure; } /** * Resolve the closure with the given arguments. * * @return mixed */ public function __invoke() { return \call_user_func_array($this->closure, \func_get_args()); } /** * Gets the closure. * * @return \Closure */ public function getClosure() { return $this->closure; } /** * Get the serializable representation of the closure. * * @return array */ public function __serialize() { if ($this->scope === null) { $this->scope = new ClosureScope(); $this->scope->toSerialize++; } $this->scope->serializations++; $scope = $object = null; $reflector = $this->getReflector(); if ($reflector->isBindingRequired()) { $object = $reflector->getClosureThis(); static::wrapClosures($object, $this->scope); } if ($scope = $reflector->getClosureScopeClass()) { $scope = $scope->name; } $this->reference = \spl_object_hash($this->closure); $this->scope[$this->closure] = $this; $use = $reflector->getUseVariables(); if (static::$transformUseVariables) { $use = \call_user_func(static::$transformUseVariables, $reflector->getUseVariables()); } $code = $reflector->getCode(); $this->mapByReference($use); $data = ['use' => $use, 'function' => $code, 'scope' => $scope, 'this' => $object, 'self' => $this->reference]; if (!--$this->scope->serializations && !--$this->scope->toSerialize) { $this->scope = null; } return $data; } /** * Restore the closure after serialization. * * @param array $data * @return void */ public function __unserialize($data) { ClosureStream::register(); $this->code = $data; unset($data); $this->code['objects'] = []; if ($this->code['use']) { $this->scope = new ClosureScope(); if (static::$resolveUseVariables) { $this->code['use'] = \call_user_func(static::$resolveUseVariables, $this->code['use']); } $this->mapPointers($this->code['use']); \extract($this->code['use'], \EXTR_OVERWRITE | \EXTR_REFS); $this->scope = null; } $this->closure = (include ClosureStream::STREAM_PROTO . '://' . $this->code['function']); if ($this->code['this'] === $this) { $this->code['this'] = null; } $this->closure = $this->closure->bindTo($this->code['this'], $this->code['scope']); if (!empty($this->code['objects'])) { foreach ($this->code['objects'] as $item) { $item['property']->setValue($item['instance'], $item['object']->getClosure()); } } $this->code = $this->code['function']; } /** * Ensures the given closures are serializable. * * @param mixed $data * @param \Laravel\SerializableClosure\Support\ClosureScope $storage * @return void */ public static function wrapClosures(&$data, $storage) { if ($data instanceof Closure) { $data = new static($data); } elseif (\is_array($data)) { if (isset($data[self::ARRAY_RECURSIVE_KEY])) { return; } $data[self::ARRAY_RECURSIVE_KEY] = \true; foreach ($data as $key => &$value) { if ($key === self::ARRAY_RECURSIVE_KEY) { continue; } static::wrapClosures($value, $storage); } unset($value); unset($data[self::ARRAY_RECURSIVE_KEY]); } elseif ($data instanceof \stdClass) { if (isset($storage[$data])) { $data = $storage[$data]; return; } $data = $storage[$data] = clone $data; foreach ($data as &$value) { static::wrapClosures($value, $storage); } unset($value); } elseif (\is_object($data) && !$data instanceof static && !$data instanceof UnitEnum) { if (isset($storage[$data])) { $data = $storage[$data]; return; } $instance = $data; $reflection = new ReflectionObject($instance); if (!$reflection->isUserDefined()) { $storage[$instance] = $data; return; } $storage[$instance] = $data = $reflection->newInstanceWithoutConstructor(); do { if (!$reflection->isUserDefined()) { break; } foreach ($reflection->getProperties() as $property) { if ($property->isStatic() || !$property->getDeclaringClass()->isUserDefined()) { continue; } $property->setAccessible(\true); if (\PHP_VERSION >= 7.4 && !$property->isInitialized($instance)) { continue; } $value = $property->getValue($instance); if (\is_array($value) || \is_object($value)) { static::wrapClosures($value, $storage); } $property->setValue($data, $value); } } while ($reflection = $reflection->getParentClass()); } } /** * Gets the closure's reflector. * * @return \Laravel\SerializableClosure\Support\ReflectionClosure */ public function getReflector() { if ($this->reflector === null) { $this->code = null; $this->reflector = new ReflectionClosure($this->closure); } return $this->reflector; } /** * Internal method used to map closure pointers. * * @param mixed $data * @return void */ protected function mapPointers(&$data) { $scope = $this->scope; if ($data instanceof static) { $data =& $data->closure; } elseif (\is_array($data)) { if (isset($data[self::ARRAY_RECURSIVE_KEY])) { return; } $data[self::ARRAY_RECURSIVE_KEY] = \true; foreach ($data as $key => &$value) { if ($key === self::ARRAY_RECURSIVE_KEY) { continue; } elseif ($value instanceof static) { $data[$key] =& $value->closure; } elseif ($value instanceof SelfReference && $value->hash === $this->code['self']) { $data[$key] =& $this->closure; } else { $this->mapPointers($value); } } unset($value); unset($data[self::ARRAY_RECURSIVE_KEY]); } elseif ($data instanceof \stdClass) { if (isset($scope[$data])) { return; } $scope[$data] = \true; foreach ($data as $key => &$value) { if ($value instanceof SelfReference && $value->hash === $this->code['self']) { $data->{$key} =& $this->closure; } elseif (\is_array($value) || \is_object($value)) { $this->mapPointers($value); } } unset($value); } elseif (\is_object($data) && !$data instanceof Closure) { if (isset($scope[$data])) { return; } $scope[$data] = \true; $reflection = new ReflectionObject($data); do { if (!$reflection->isUserDefined()) { break; } foreach ($reflection->getProperties() as $property) { if ($property->isStatic() || !$property->getDeclaringClass()->isUserDefined()) { continue; } $property->setAccessible(\true); if (\PHP_VERSION >= 7.4 && !$property->isInitialized($data)) { continue; } if (\PHP_VERSION >= 8.1 && $property->isReadOnly()) { continue; } $item = $property->getValue($data); if ($item instanceof SerializableClosure || $item instanceof UnsignedSerializableClosure || $item instanceof SelfReference && $item->hash === $this->code['self']) { $this->code['objects'][] = ['instance' => $data, 'property' => $property, 'object' => $item instanceof SelfReference ? $this : $item]; } elseif (\is_array($item) || \is_object($item)) { $this->mapPointers($item); $property->setValue($data, $item); } } } while ($reflection = $reflection->getParentClass()); } } /** * Internal method used to map closures by reference. * * @param mixed $data * @return void */ protected function mapByReference(&$data) { if ($data instanceof Closure) { if ($data === $this->closure) { $data = new SelfReference($this->reference); return; } if (isset($this->scope[$data])) { $data = $this->scope[$data]; return; } $instance = new static($data); $instance->scope = $this->scope; $data = $this->scope[$data] = $instance; } elseif (\is_array($data)) { if (isset($data[self::ARRAY_RECURSIVE_KEY])) { return; } $data[self::ARRAY_RECURSIVE_KEY] = \true; foreach ($data as $key => &$value) { if ($key === self::ARRAY_RECURSIVE_KEY) { continue; } $this->mapByReference($value); } unset($value); unset($data[self::ARRAY_RECURSIVE_KEY]); } elseif ($data instanceof \stdClass) { if (isset($this->scope[$data])) { $data = $this->scope[$data]; return; } $instance = $data; $this->scope[$instance] = $data = clone $data; foreach ($data as &$value) { $this->mapByReference($value); } unset($value); } elseif (\is_object($data) && !$data instanceof SerializableClosure && !$data instanceof UnsignedSerializableClosure) { if (isset($this->scope[$data])) { $data = $this->scope[$data]; return; } $instance = $data; if ($data instanceof DateTimeInterface) { $this->scope[$instance] = $data; return; } if ($data instanceof UnitEnum) { $this->scope[$instance] = $data; return; } $reflection = new ReflectionObject($data); if (!$reflection->isUserDefined()) { $this->scope[$instance] = $data; return; } $this->scope[$instance] = $data = $reflection->newInstanceWithoutConstructor(); do { if (!$reflection->isUserDefined()) { break; } foreach ($reflection->getProperties() as $property) { if ($property->isStatic() || !$property->getDeclaringClass()->isUserDefined()) { continue; } $property->setAccessible(\true); if (\PHP_VERSION >= 7.4 && !$property->isInitialized($instance)) { continue; } if (\PHP_VERSION >= 8.1 && $property->isReadOnly() && $property->class !== $reflection->name) { continue; } $value = $property->getValue($instance); if (\is_array($value) || \is_object($value)) { $this->mapByReference($value); } $property->setValue($data, $value); } } while ($reflection = $reflection->getParentClass()); } } } serializable-closure/src/Serializers/Signed.php 0000777 00000004106 15251306123 0015677 0 ustar 00 <?php namespace Rvx\Laravel\SerializableClosure\Serializers; use Rvx\Laravel\SerializableClosure\Contracts\Serializable; use Rvx\Laravel\SerializableClosure\Exceptions\InvalidSignatureException; use Rvx\Laravel\SerializableClosure\Exceptions\MissingSecretKeyException; class Signed implements Serializable { /** * The signer that will sign and verify the closure's signature. * * @var \Laravel\SerializableClosure\Contracts\Signer|null */ public static $signer; /** * The closure to be serialized/unserialized. * * @var \Closure */ protected $closure; /** * Creates a new serializable closure instance. * * @param \Closure $closure * @return void */ public function __construct($closure) { $this->closure = $closure; } /** * Resolve the closure with the given arguments. * * @return mixed */ public function __invoke() { return \call_user_func_array($this->closure, \func_get_args()); } /** * Gets the closure. * * @return \Closure */ public function getClosure() { return $this->closure; } /** * Get the serializable representation of the closure. * * @return array */ public function __serialize() { if (!static::$signer) { throw new MissingSecretKeyException(); } return static::$signer->sign(\serialize(new Native($this->closure))); } /** * Restore the closure after serialization. * * @param array $signature * @return void * * @throws \Laravel\SerializableClosure\Exceptions\InvalidSignatureException */ public function __unserialize($signature) { if (static::$signer && !static::$signer->verify($signature)) { throw new InvalidSignatureException(); } /** @var \Laravel\SerializableClosure\Contracts\Serializable $serializable */ $serializable = \unserialize($signature['serializable']); $this->closure = $serializable->getClosure(); } } serializable-closure/src/SerializableClosure.php 0000777 00000006353 15251306123 0016143 0 ustar 00 <?php namespace Rvx\Laravel\SerializableClosure; use Closure; use Rvx\Laravel\SerializableClosure\Exceptions\InvalidSignatureException; use Rvx\Laravel\SerializableClosure\Exceptions\PhpVersionNotSupportedException; use Rvx\Laravel\SerializableClosure\Serializers\Signed; use Rvx\Laravel\SerializableClosure\Signers\Hmac; class SerializableClosure { /** * The closure's serializable. * * @var \Laravel\SerializableClosure\Contracts\Serializable */ protected $serializable; /** * Creates a new serializable closure instance. * * @param \Closure $closure * @return void */ public function __construct(Closure $closure) { if (\PHP_VERSION_ID < 70400) { throw new PhpVersionNotSupportedException(); } $this->serializable = Serializers\Signed::$signer ? new Serializers\Signed($closure) : new Serializers\Native($closure); } /** * Resolve the closure with the given arguments. * * @return mixed */ public function __invoke() { if (\PHP_VERSION_ID < 70400) { throw new PhpVersionNotSupportedException(); } return \call_user_func_array($this->serializable, \func_get_args()); } /** * Gets the closure. * * @return \Closure */ public function getClosure() { if (\PHP_VERSION_ID < 70400) { throw new PhpVersionNotSupportedException(); } return $this->serializable->getClosure(); } /** * Create a new unsigned serializable closure instance. * * @param Closure $closure * @return \Laravel\SerializableClosure\UnsignedSerializableClosure */ public static function unsigned(Closure $closure) { return new UnsignedSerializableClosure($closure); } /** * Sets the serializable closure secret key. * * @param string|null $secret * @return void */ public static function setSecretKey($secret) { Serializers\Signed::$signer = $secret ? new Hmac($secret) : null; } /** * Sets the serializable closure secret key. * * @param \Closure|null $transformer * @return void */ public static function transformUseVariablesUsing($transformer) { Serializers\Native::$transformUseVariables = $transformer; } /** * Sets the serializable closure secret key. * * @param \Closure|null $resolver * @return void */ public static function resolveUseVariablesUsing($resolver) { Serializers\Native::$resolveUseVariables = $resolver; } /** * Get the serializable representation of the closure. * * @return array */ public function __serialize() { return ['serializable' => $this->serializable]; } /** * Restore the closure after serialization. * * @param array $data * @return void * * @throws \Laravel\SerializableClosure\Exceptions\InvalidSignatureException */ public function __unserialize($data) { if (Signed::$signer && !$data['serializable'] instanceof Signed) { throw new InvalidSignatureException(); } $this->serializable = $data['serializable']; } }
| ver. 1.6 |
Github
|
.
| PHP 8.1.34 | Генерация страницы: 0 |
proxy
|
phpinfo
|
Настройка