pref: 增加服务类优化UI版面

This commit is contained in:
Ying
2023-06-19 14:32:30 +08:00
parent 27eda6f37f
commit 2b8f874450
148 changed files with 3933 additions and 9286 deletions

View File

@@ -8,9 +8,10 @@ $baseDir = dirname($vendorDir);
return array(
'Attribute' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
'JsonException' => $vendorDir . '/symfony/polyfill-php73/Resources/stubs/JsonException.php',
'Normalizer' => $vendorDir . '/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php',
'PhpToken' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php',
'Stringable' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',
'Stringable' => $vendorDir . '/myclabs/php-enum/stubs/Stringable.php',
'UnhandledMatchError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
'ValueError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
);

View File

@@ -7,23 +7,25 @@ $baseDir = dirname($vendorDir);
return array(
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
'9b552a3cc426e3287cc811caefa3cf53' => $vendorDir . '/topthink/think-helper/src/helper.php',
'6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php',
'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
'9b552a3cc426e3287cc811caefa3cf53' => $vendorDir . '/topthink/think-helper/src/helper.php',
'60799491728b879e74601d83e38b2cad' => $vendorDir . '/illuminate/collections/helpers.php',
'320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php',
'8825ede83f2f289127722d4e842cf7e8' => $vendorDir . '/symfony/polyfill-intl-grapheme/bootstrap.php',
'e69f7f6ee287b969198c3c9d6777bd38' => $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php',
'a1105708a18b76903365ca1c4aa61b02' => $vendorDir . '/symfony/translation/Resources/functions.php',
'253c157292f75eb38082b5acb06f3f01' => $vendorDir . '/nikic/fast-route/src/functions.php',
'538ca81a9a966a6716601ecf48f4eaef' => $vendorDir . '/opis/closure/functions.php',
'7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php',
'b6b991a57620e2fb6b2f66f03fe9ddc2' => $vendorDir . '/symfony/string/Resources/functions.php',
'2cffec82183ee1cea088009cef9a6fc3' => $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php',
'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php',
'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
'72579e7bd17821bb1321b87411366eae' => $vendorDir . '/illuminate/support/helpers.php',
'0d59ee240a4cd96ddbb4ff164fccea4d' => $vendorDir . '/symfony/polyfill-php73/bootstrap.php',
'35fab96057f1bf5e7aba31a8a6d5fdde' => $vendorDir . '/topthink/think-orm/stubs/load_stubs.php',
'6b998e7ad3182c0d21d23780badfa07b' => $vendorDir . '/yansongda/supports/src/Functions.php',
'37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
'b33e3d135e5d9e47d845c576147bda89' => $vendorDir . '/php-di/php-di/src/functions.php',
'a1105708a18b76903365ca1c4aa61b02' => $vendorDir . '/symfony/translation/Resources/functions.php',
'667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php',
'8c783b3a3de2f6d9177022b5ccdcc841' => $vendorDir . '/yansongda/pay/src/Functions.php',
'fe146f35de045d8ffe923710b1f98ecc' => $baseDir . '/support/helpers.php',

View File

@@ -6,7 +6,8 @@ $vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(
'think\\' => array($vendorDir . '/topthink/think-cache/src', $vendorDir . '/topthink/think-container/src', $vendorDir . '/topthink/think-helper/src', $vendorDir . '/topthink/think-image/src', $vendorDir . '/topthink/think-orm/src', $vendorDir . '/topthink/think-template/src', $vendorDir . '/topthink/think-validate/src'),
'voku\\' => array($vendorDir . '/voku/portable-ascii/src/voku'),
'think\\' => array($vendorDir . '/topthink/think-container/src', $vendorDir . '/topthink/think-helper/src', $vendorDir . '/topthink/think-image/src', $vendorDir . '/topthink/think-orm/src', $vendorDir . '/topthink/think-template/src', $vendorDir . '/topthink/think-validate/src'),
'support\\' => array($vendorDir . '/workerman/webman-framework/src/support'),
'app\\' => array($baseDir . '/app'),
'ZipStream\\' => array($vendorDir . '/maennchen/zipstream-php/src'),
@@ -16,7 +17,6 @@ return array(
'Workerman\\RedisQueue\\' => array($vendorDir . '/workerman/redis-queue/src'),
'Workerman\\' => array($vendorDir . '/workerman/workerman'),
'Webman\\ThinkOrm\\' => array($vendorDir . '/webman/think-orm/src'),
'Webman\\ThinkCache\\' => array($vendorDir . '/webman/think-cache/src'),
'Webman\\RedisQueue\\' => array($vendorDir . '/webman/redis-queue/src'),
'Webman\\GatewayWorker\\' => array($vendorDir . '/webman/gateway-worker/src'),
'Webman\\Event\\' => array($vendorDir . '/webman/event/src'),
@@ -24,16 +24,20 @@ return array(
'Webman\\Captcha\\' => array($vendorDir . '/webman/captcha/src'),
'Webman\\' => array($vendorDir . '/workerman/webman-framework/src'),
'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'),
'Symfony\\Polyfill\\Php73\\' => array($vendorDir . '/symfony/polyfill-php73'),
'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
'Symfony\\Polyfill\\Intl\\Normalizer\\' => array($vendorDir . '/symfony/polyfill-intl-normalizer'),
'Symfony\\Polyfill\\Intl\\Grapheme\\' => array($vendorDir . '/symfony/polyfill-intl-grapheme'),
'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'),
'Symfony\\Contracts\\Translation\\' => array($vendorDir . '/symfony/translation-contracts'),
'Symfony\\Contracts\\Service\\' => array($vendorDir . '/symfony/service-contracts'),
'Symfony\\Contracts\\Cache\\' => array($vendorDir . '/symfony/cache-contracts'),
'Symfony\\Component\\VarExporter\\' => array($vendorDir . '/symfony/var-exporter'),
'Symfony\\Component\\VarDumper\\' => array($vendorDir . '/symfony/var-dumper'),
'Symfony\\Component\\Translation\\' => array($vendorDir . '/symfony/translation'),
'Symfony\\Component\\String\\' => array($vendorDir . '/symfony/string'),
'Symfony\\Component\\Console\\' => array($vendorDir . '/symfony/console'),
'Symfony\\Component\\Cache\\' => array($vendorDir . '/symfony/cache'),
'Support\\View\\' => array($vendorDir . '/workerman/webman-framework/src/support/view'),
'Support\\Exception\\' => array($vendorDir . '/workerman/webman-framework/src/support/exception'),
'Support\\Bootstrap\\' => array($vendorDir . '/workerman/webman-framework/src/support/bootstrap'),
@@ -49,12 +53,14 @@ return array(
'PhpDocReader\\' => array($vendorDir . '/php-di/phpdoc-reader/src/PhpDocReader'),
'PHPMailer\\PHPMailer\\' => array($vendorDir . '/phpmailer/phpmailer/src'),
'Overtrue\\Pinyin\\' => array($vendorDir . '/overtrue/pinyin/src'),
'Opis\\Closure\\' => array($vendorDir . '/opis/closure/src'),
'MyCLabs\\Enum\\' => array($vendorDir . '/myclabs/php-enum/src'),
'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'),
'Matrix\\' => array($vendorDir . '/markbaker/matrix/classes/src'),
'Laravel\\SerializableClosure\\' => array($vendorDir . '/laravel/serializable-closure/src'),
'Invoker\\' => array($vendorDir . '/php-di/invoker/src'),
'Illuminate\\Support\\' => array($vendorDir . '/illuminate/collections', $vendorDir . '/illuminate/conditionable', $vendorDir . '/illuminate/macroable', $vendorDir . '/illuminate/support'),
'Illuminate\\Redis\\' => array($vendorDir . '/illuminate/redis'),
'Illuminate\\Contracts\\' => array($vendorDir . '/illuminate/contracts'),
'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'),
'GuzzleHttp\\Promise\\' => array($vendorDir . '/guzzlehttp/promises/src'),
'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'),
@@ -65,6 +71,7 @@ return array(
'DI\\' => array($vendorDir . '/php-di/php-di/src'),
'DASPRiD\\Enum\\' => array($vendorDir . '/dasprid/enum/src'),
'Complex\\' => array($vendorDir . '/markbaker/complex/classes/src'),
'Carbon\\' => array($vendorDir . '/nesbot/carbon/src/Carbon'),
'BaconQrCode\\' => array($vendorDir . '/bacon/bacon-qr-code/src'),
'' => array($baseDir . '/'),
);

View File

@@ -8,29 +8,35 @@ class ComposerStaticInitfa49c619328634587e27f2ef69b215b7
{
public static $files = array (
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
'9b552a3cc426e3287cc811caefa3cf53' => __DIR__ . '/..' . '/topthink/think-helper/src/helper.php',
'6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php',
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
'9b552a3cc426e3287cc811caefa3cf53' => __DIR__ . '/..' . '/topthink/think-helper/src/helper.php',
'60799491728b879e74601d83e38b2cad' => __DIR__ . '/..' . '/illuminate/collections/helpers.php',
'320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
'8825ede83f2f289127722d4e842cf7e8' => __DIR__ . '/..' . '/symfony/polyfill-intl-grapheme/bootstrap.php',
'e69f7f6ee287b969198c3c9d6777bd38' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/bootstrap.php',
'a1105708a18b76903365ca1c4aa61b02' => __DIR__ . '/..' . '/symfony/translation/Resources/functions.php',
'253c157292f75eb38082b5acb06f3f01' => __DIR__ . '/..' . '/nikic/fast-route/src/functions.php',
'538ca81a9a966a6716601ecf48f4eaef' => __DIR__ . '/..' . '/opis/closure/functions.php',
'7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
'b6b991a57620e2fb6b2f66f03fe9ddc2' => __DIR__ . '/..' . '/symfony/string/Resources/functions.php',
'2cffec82183ee1cea088009cef9a6fc3' => __DIR__ . '/..' . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php',
'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php',
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
'72579e7bd17821bb1321b87411366eae' => __DIR__ . '/..' . '/illuminate/support/helpers.php',
'0d59ee240a4cd96ddbb4ff164fccea4d' => __DIR__ . '/..' . '/symfony/polyfill-php73/bootstrap.php',
'35fab96057f1bf5e7aba31a8a6d5fdde' => __DIR__ . '/..' . '/topthink/think-orm/stubs/load_stubs.php',
'6b998e7ad3182c0d21d23780badfa07b' => __DIR__ . '/..' . '/yansongda/supports/src/Functions.php',
'37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php',
'b33e3d135e5d9e47d845c576147bda89' => __DIR__ . '/..' . '/php-di/php-di/src/functions.php',
'a1105708a18b76903365ca1c4aa61b02' => __DIR__ . '/..' . '/symfony/translation/Resources/functions.php',
'667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php',
'8c783b3a3de2f6d9177022b5ccdcc841' => __DIR__ . '/..' . '/yansongda/pay/src/Functions.php',
'fe146f35de045d8ffe923710b1f98ecc' => __DIR__ . '/../..' . '/support/helpers.php',
);
public static $prefixLengthsPsr4 = array (
'v' =>
array (
'voku\\' => 5,
),
't' =>
array (
'think\\' => 6,
@@ -58,7 +64,6 @@ class ComposerStaticInitfa49c619328634587e27f2ef69b215b7
'Workerman\\RedisQueue\\' => 21,
'Workerman\\' => 10,
'Webman\\ThinkOrm\\' => 16,
'Webman\\ThinkCache\\' => 18,
'Webman\\RedisQueue\\' => 18,
'Webman\\GatewayWorker\\' => 21,
'Webman\\Event\\' => 13,
@@ -69,16 +74,20 @@ class ComposerStaticInitfa49c619328634587e27f2ef69b215b7
'S' =>
array (
'Symfony\\Polyfill\\Php80\\' => 23,
'Symfony\\Polyfill\\Php73\\' => 23,
'Symfony\\Polyfill\\Mbstring\\' => 26,
'Symfony\\Polyfill\\Intl\\Normalizer\\' => 33,
'Symfony\\Polyfill\\Intl\\Grapheme\\' => 31,
'Symfony\\Polyfill\\Ctype\\' => 23,
'Symfony\\Contracts\\Translation\\' => 30,
'Symfony\\Contracts\\Service\\' => 26,
'Symfony\\Contracts\\Cache\\' => 24,
'Symfony\\Component\\VarExporter\\' => 30,
'Symfony\\Component\\VarDumper\\' => 28,
'Symfony\\Component\\Translation\\' => 30,
'Symfony\\Component\\String\\' => 25,
'Symfony\\Component\\Console\\' => 26,
'Symfony\\Component\\Cache\\' => 24,
'Support\\View\\' => 13,
'Support\\Exception\\' => 18,
'Support\\Bootstrap\\' => 18,
@@ -100,7 +109,6 @@ class ComposerStaticInitfa49c619328634587e27f2ef69b215b7
'O' =>
array (
'Overtrue\\Pinyin\\' => 16,
'Opis\\Closure\\' => 13,
),
'M' =>
array (
@@ -115,6 +123,9 @@ class ComposerStaticInitfa49c619328634587e27f2ef69b215b7
'I' =>
array (
'Invoker\\' => 8,
'Illuminate\\Support\\' => 19,
'Illuminate\\Redis\\' => 17,
'Illuminate\\Contracts\\' => 21,
),
'G' =>
array (
@@ -140,6 +151,7 @@ class ComposerStaticInitfa49c619328634587e27f2ef69b215b7
'C' =>
array (
'Complex\\' => 8,
'Carbon\\' => 7,
),
'B' =>
array (
@@ -148,15 +160,18 @@ class ComposerStaticInitfa49c619328634587e27f2ef69b215b7
);
public static $prefixDirsPsr4 = array (
'voku\\' =>
array (
0 => __DIR__ . '/..' . '/voku/portable-ascii/src/voku',
),
'think\\' =>
array (
0 => __DIR__ . '/..' . '/topthink/think-cache/src',
1 => __DIR__ . '/..' . '/topthink/think-container/src',
2 => __DIR__ . '/..' . '/topthink/think-helper/src',
3 => __DIR__ . '/..' . '/topthink/think-image/src',
4 => __DIR__ . '/..' . '/topthink/think-orm/src',
5 => __DIR__ . '/..' . '/topthink/think-template/src',
6 => __DIR__ . '/..' . '/topthink/think-validate/src',
0 => __DIR__ . '/..' . '/topthink/think-container/src',
1 => __DIR__ . '/..' . '/topthink/think-helper/src',
2 => __DIR__ . '/..' . '/topthink/think-image/src',
3 => __DIR__ . '/..' . '/topthink/think-orm/src',
4 => __DIR__ . '/..' . '/topthink/think-template/src',
5 => __DIR__ . '/..' . '/topthink/think-validate/src',
),
'support\\' =>
array (
@@ -194,10 +209,6 @@ class ComposerStaticInitfa49c619328634587e27f2ef69b215b7
array (
0 => __DIR__ . '/..' . '/webman/think-orm/src',
),
'Webman\\ThinkCache\\' =>
array (
0 => __DIR__ . '/..' . '/webman/think-cache/src',
),
'Webman\\RedisQueue\\' =>
array (
0 => __DIR__ . '/..' . '/webman/redis-queue/src',
@@ -226,6 +237,10 @@ class ComposerStaticInitfa49c619328634587e27f2ef69b215b7
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-php80',
),
'Symfony\\Polyfill\\Php73\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-php73',
),
'Symfony\\Polyfill\\Mbstring\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring',
@@ -250,6 +265,14 @@ class ComposerStaticInitfa49c619328634587e27f2ef69b215b7
array (
0 => __DIR__ . '/..' . '/symfony/service-contracts',
),
'Symfony\\Contracts\\Cache\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/cache-contracts',
),
'Symfony\\Component\\VarExporter\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/var-exporter',
),
'Symfony\\Component\\VarDumper\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/var-dumper',
@@ -266,6 +289,10 @@ class ComposerStaticInitfa49c619328634587e27f2ef69b215b7
array (
0 => __DIR__ . '/..' . '/symfony/console',
),
'Symfony\\Component\\Cache\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/cache',
),
'Support\\View\\' =>
array (
0 => __DIR__ . '/..' . '/workerman/webman-framework/src/support/view',
@@ -327,10 +354,6 @@ class ComposerStaticInitfa49c619328634587e27f2ef69b215b7
array (
0 => __DIR__ . '/..' . '/overtrue/pinyin/src',
),
'Opis\\Closure\\' =>
array (
0 => __DIR__ . '/..' . '/opis/closure/src',
),
'MyCLabs\\Enum\\' =>
array (
0 => __DIR__ . '/..' . '/myclabs/php-enum/src',
@@ -351,6 +374,21 @@ class ComposerStaticInitfa49c619328634587e27f2ef69b215b7
array (
0 => __DIR__ . '/..' . '/php-di/invoker/src',
),
'Illuminate\\Support\\' =>
array (
0 => __DIR__ . '/..' . '/illuminate/collections',
1 => __DIR__ . '/..' . '/illuminate/conditionable',
2 => __DIR__ . '/..' . '/illuminate/macroable',
3 => __DIR__ . '/..' . '/illuminate/support',
),
'Illuminate\\Redis\\' =>
array (
0 => __DIR__ . '/..' . '/illuminate/redis',
),
'Illuminate\\Contracts\\' =>
array (
0 => __DIR__ . '/..' . '/illuminate/contracts',
),
'GuzzleHttp\\Psr7\\' =>
array (
0 => __DIR__ . '/..' . '/guzzlehttp/psr7/src',
@@ -391,6 +429,10 @@ class ComposerStaticInitfa49c619328634587e27f2ef69b215b7
array (
0 => __DIR__ . '/..' . '/markbaker/complex/classes/src',
),
'Carbon\\' =>
array (
0 => __DIR__ . '/..' . '/nesbot/carbon/src/Carbon',
),
'BaconQrCode\\' =>
array (
0 => __DIR__ . '/..' . '/bacon/bacon-qr-code/src',
@@ -418,9 +460,10 @@ class ComposerStaticInitfa49c619328634587e27f2ef69b215b7
public static $classMap = array (
'Attribute' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
'JsonException' => __DIR__ . '/..' . '/symfony/polyfill-php73/Resources/stubs/JsonException.php',
'Normalizer' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php',
'PhpToken' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php',
'Stringable' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',
'Stringable' => __DIR__ . '/..' . '/myclabs/php-enum/stubs/Stringable.php',
'UnhandledMatchError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
'ValueError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
);

File diff suppressed because it is too large Load Diff

View File

@@ -82,6 +82,60 @@
'aliases' => array(),
'dev_requirement' => false,
),
'illuminate/collections' => array(
'pretty_version' => 'v9.52.9',
'version' => '9.52.9.0',
'reference' => '0168d0e44ea0c4fe5451fe08cde7049b9e9f9741',
'type' => 'library',
'install_path' => __DIR__ . '/../illuminate/collections',
'aliases' => array(),
'dev_requirement' => false,
),
'illuminate/conditionable' => array(
'pretty_version' => 'v9.52.9',
'version' => '9.52.9.0',
'reference' => 'bea24daa0fa84b7e7b0d5b84f62c71b7e2dc3364',
'type' => 'library',
'install_path' => __DIR__ . '/../illuminate/conditionable',
'aliases' => array(),
'dev_requirement' => false,
),
'illuminate/contracts' => array(
'pretty_version' => 'v9.52.9',
'version' => '9.52.9.0',
'reference' => '44f65d723b13823baa02ff69751a5948bde60c22',
'type' => 'library',
'install_path' => __DIR__ . '/../illuminate/contracts',
'aliases' => array(),
'dev_requirement' => false,
),
'illuminate/macroable' => array(
'pretty_version' => 'v9.52.9',
'version' => '9.52.9.0',
'reference' => 'e3bfaf6401742a9c6abca61b9b10e998e5b6449a',
'type' => 'library',
'install_path' => __DIR__ . '/../illuminate/macroable',
'aliases' => array(),
'dev_requirement' => false,
),
'illuminate/redis' => array(
'pretty_version' => 'v9.52.9',
'version' => '9.52.9.0',
'reference' => '856adc664a35dfcb8c59f8adbc97d5fbd250f9c2',
'type' => 'library',
'install_path' => __DIR__ . '/../illuminate/redis',
'aliases' => array(),
'dev_requirement' => false,
),
'illuminate/support' => array(
'pretty_version' => 'v9.52.9',
'version' => '9.52.9.0',
'reference' => '3fc1d9deb1dc8c256c3394e1547dccdd386bb2f5',
'type' => 'library',
'install_path' => __DIR__ . '/../illuminate/support',
'aliases' => array(),
'dev_requirement' => false,
),
'laravel/serializable-closure' => array(
'pretty_version' => 'v1.3.0',
'version' => '1.3.0.0',
@@ -145,6 +199,15 @@
'aliases' => array(),
'dev_requirement' => false,
),
'nesbot/carbon' => array(
'pretty_version' => '2.67.0',
'version' => '2.67.0.0',
'reference' => 'c1001b3bc75039b07f38a79db5237c4c529e04c8',
'type' => 'library',
'install_path' => __DIR__ . '/../nesbot/carbon',
'aliases' => array(),
'dev_requirement' => false,
),
'nikic/fast-route' => array(
'pretty_version' => 'v1.3.0',
'version' => '1.3.0.0',
@@ -154,15 +217,6 @@
'aliases' => array(),
'dev_requirement' => false,
),
'opis/closure' => array(
'pretty_version' => '3.6.3',
'version' => '3.6.3.0',
'reference' => '3d81e4309d2a927abbe66df935f4bb60082805ad',
'type' => 'library',
'install_path' => __DIR__ . '/../opis/closure',
'aliases' => array(),
'dev_requirement' => false,
),
'overtrue/pinyin' => array(
'pretty_version' => '5.0.0',
'version' => '5.0.0.0',
@@ -226,6 +280,12 @@
'aliases' => array(),
'dev_requirement' => false,
),
'psr/cache-implementation' => array(
'dev_requirement' => false,
'provided' => array(
0 => '1.0|2.0',
),
),
'psr/container' => array(
'pretty_version' => '1.1.1',
'version' => '1.1.1.0',
@@ -320,6 +380,12 @@
'aliases' => array(),
'dev_requirement' => false,
),
'psr/simple-cache-implementation' => array(
'dev_requirement' => false,
'provided' => array(
0 => '1.0|2.0',
),
),
'ralouphie/getallheaders' => array(
'pretty_version' => '3.0.3',
'version' => '3.0.3.0',
@@ -329,6 +395,30 @@
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/cache' => array(
'pretty_version' => 'v5.4.23',
'version' => '5.4.23.0',
'reference' => '983c79ff28612cdfd66d8e44e1a06e5afc87e107',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/cache',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/cache-contracts' => array(
'pretty_version' => 'v2.5.2',
'version' => '2.5.2.0',
'reference' => '64be4a7acb83b6f2bf6de9a02cee6dad41277ebc',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/cache-contracts',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/cache-implementation' => array(
'dev_requirement' => false,
'provided' => array(
0 => '1.0|2.0',
),
),
'symfony/console' => array(
'pretty_version' => 'v6.0.19',
'version' => '6.0.19.0',
@@ -383,6 +473,15 @@
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/polyfill-php73' => array(
'pretty_version' => 'v1.27.0',
'version' => '1.27.0.0',
'reference' => '9e8ecb5f92152187c4799efd3c96b78ccab18ff9',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-php73',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/polyfill-php80' => array(
'pretty_version' => 'v1.27.0',
'version' => '1.27.0.0',
@@ -411,9 +510,9 @@
'dev_requirement' => false,
),
'symfony/translation' => array(
'pretty_version' => 'v5.4.22',
'version' => '5.4.22.0',
'reference' => '9a401392f01bc385aa42760eff481d213a0cc2ba',
'pretty_version' => 'v5.4.24',
'version' => '5.4.24.0',
'reference' => 'de237e59c5833422342be67402d487fbf50334ff',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/translation',
'aliases' => array(),
@@ -443,12 +542,12 @@
'aliases' => array(),
'dev_requirement' => false,
),
'topthink/think-cache' => array(
'pretty_version' => 'v2.0.7',
'version' => '2.0.7.0',
'reference' => '7b6ace7eb9b569fe95000b254000bbafa3c7dfee',
'symfony/var-exporter' => array(
'pretty_version' => 'v6.0.19',
'version' => '6.0.19.0',
'reference' => 'df56f53818c2d5d9f683f4ad2e365ba73a3b69d2',
'type' => 'library',
'install_path' => __DIR__ . '/../topthink/think-cache',
'install_path' => __DIR__ . '/../symfony/var-exporter',
'aliases' => array(),
'dev_requirement' => false,
),
@@ -506,6 +605,15 @@
'aliases' => array(),
'dev_requirement' => false,
),
'voku/portable-ascii' => array(
'pretty_version' => '2.0.1',
'version' => '2.0.1.0',
'reference' => 'b56450eed252f6801410d810c8e1727224ae0743',
'type' => 'library',
'install_path' => __DIR__ . '/../voku/portable-ascii',
'aliases' => array(),
'dev_requirement' => false,
),
'webman/captcha' => array(
'pretty_version' => 'v1.0.2',
'version' => '1.0.2.0',
@@ -551,15 +659,6 @@
'aliases' => array(),
'dev_requirement' => false,
),
'webman/think-cache' => array(
'pretty_version' => 'v1.0.2',
'version' => '1.0.2.0',
'reference' => '0420d03a564e3513b7578ec475c6699ec02cd081',
'type' => 'library',
'install_path' => __DIR__ . '/../webman/think-cache',
'aliases' => array(),
'dev_requirement' => false,
),
'webman/think-orm' => array(
'pretty_version' => 'v1.1.0',
'version' => '1.1.0.0',

View File

@@ -1,260 +0,0 @@
CHANGELOG
---------
### v3.6.2, 2021.04.09
- Fixed string interpolation
### v3.6.1, 2020.11.07
- Fixed serialization error [#84](https://github.com/opis/closure/issues/84)
### v3.6.0, 2020.10.12
- Initial PHP 8 Support [#67](https://github.com/opis/closure/issues/67).
### v3.5.7, 2020.09.06
- Fixed issue [#76](https://github.com/opis/closure/issues/76).
- Fixed issue [#78](https://github.com/opis/closure/issues/78).
### v3.5.6, 2020.08.11
- Fixed issue [#70](https://github.com/opis/closure/issues/70)
### v3.5.5, 2020.06.17
- Fixed a false-positive when using `Opis\Closure\ReflectionClosure::isScopeRequired` method
### v3.5.4, 2020.06.07
- Fixed a false-positive when using `Opis\Closure\ReflectionClosure::isScopeRequired` method
- Fixed a bug related to `T_STRING_VARNAME`
### v3.5.3, 2020.05.25
- Improved parser
- The class scope optimisation is no longer used. We always bind now to the closure's original class scope.
When the class scope was `null`, the optimisation failed to work as expected and kept the wrong `SerializableClosure` scope.
### v3.5.2, 2020.05.21
- Removed extra semicolon in short closures, since is not part of the closure's body.
### v3.5.1, 2019.11.30
- Bugfix. See #47
### v3.5.0, 2019.11.29
- Added support for short closures (arrow functions)
- Added `isShortClosure` method to `Opis\Closure\ReflectionClosure`
### v3.4.2, 2019.11.29
- Added `stream_set_option()`
### v3.4.1, 2019.10.19
- Fixed a [bug](https://github.com/opis/closure/issues/40) that prevented serialization to work correctly.
### v3.4.0, 2019.09.03
- Added `createClosure` static method in `Opis\Closure\SerializableClosure`.
This method creates a new closure from arbitrary code, emulating `create_function`,
but without using eval
### v3.3.1, 2019.07.10
- Use `sha1` instead of `md5` for hashing file names in `Opis\Closure\ReflectionClosure` class
### v3.3.0, 2019.05.31
- Fixed a bug that prevented signed closures to properly work when the serialized string
contains invalid UTF-8 chars. Starting with this version `json_encode` is no longer used
when signing a closure. Backward compatibility is maintained and all closures that were
previously signed using the old method will continue to work.
### v3.2.0, 2019.05.05
- Since an unsigned closure can be unserialized when no security provider is set,
there is no reason to treat differently a signed closure in the same situation.
Therefore, the `Opis\Closure\SecurityException` exception is no longer thrown when
unserializing a signed closure, if no security provider is set.
### v3.1.6, 2019.02.22
- Fixed a bug that occurred when trying to set properties of classes that were not defined in user-land.
Those properties are now ignored.
### v3.1.5, 2019.01.14
- Improved parser
### v3.1.4, 2019.01.14
- Added support for static methods that are named using PHP keywords or magic constants.
Ex: `A::new()`, `A::use()`, `A::if()`, `A::function()`, `A::__DIR__()`, etc.
- Used `@internal` to mark classes & methods that are for internal use only and
backward compatibility is not guaranteed.
### v3.1.3, 2019.01.07
- Fixed a bug that prevented traits to be correctly resolved when used by an
anonymous class
- Fixed a bug that occurred when `$this` keyword was used inside an anonymous class
### v3.1.2, 2018.12.16
* Fixed a bug regarding comma trail in group-use statements. See [issue 23](https://github.com/opis/closure/issues/23)
### v3.1.1, 2018.10.02
* Fixed a bug where `parent` keyword was treated like a class-name and scope was not added to the
serialized closure
* Fixed a bug where return type was not properly handled for nested closures
* Support for anonymous classes was improved
### v3.1.0, 2018.09.20
* Added `transformUseVariables` and `resolveUseVariables` to
`Opis\Closure\SerializableClosure` class.
* Added `removeSecurityProvider` static method to
`Opis\Closure\SerializableClosure` class.
* Fixed some security related issues where a user was able to unserialize an unsigned
closure, even when a security provider was in use.
### v3.0.12, 2018.02.23
* Bugfix. See [issue 20](https://github.com/opis/closure/issues/20)
### v3.0.11, 2018.01.22
* Bugfix. See [issue 18](https://github.com/opis/closure/issues/18)
### v3.0.10, 2018.01.04
* Improved support for PHP 7.1 & 7.2
### v3.0.9, 2018.01.04
* Fixed a bug where the return type was not properly resolved.
See [issue 17](https://github.com/opis/closure/issues/17)
* Added more tests
### v3.0.8, 2017.12.18
* Fixed a bug. See [issue 16](https://github.com/opis/closure/issues/16)
### v3.0.7, 2017.10.31
* Bugfix: static properties are ignored now, since they are not serializable
### v3.0.6, 2017.10.06
* Fixed a bug introduced by accident in 3.0.5
### v3.0.5, 2017.09.18
* Fixed a bug related to nested references
### v3.0.4, 2017.09.18
* \[*internal*\] Refactored `SerializableClosure::mapPointers` method
* \[*internal*\] Added a new optional argument to `SerializableClosure::unwrapClosures`
* \[*internal*\] Removed `SerializableClosure::getClosurePointer` method
* Fixed various bugs
### v3.0.3, 2017.09.06
* Fixed a bug related to nested object references
* \[*internal*\] `Opis\Closure\ClosureScope` now extends `SplObjectStorage`
* \[*internal*\] The `storage` property was removed from `Opis\Closure\ClosureScope`
* \[*internal*\] The `instances` and `objects` properties were removed from `Opis\Closure\ClosureContext`
### v3.0.2, 2017.08.28
* Fixed a bug where `$this` object was not handled properly inside the
`SerializableClosre::serialize` method.
### v3.0.1, 2017.04.13
* Fixed a bug in 'ignore_next' state
### v3.0.0, 2017.04.07
* Dropped PHP 5.3 support
* Moved source files from `lib` to `src` folder
* Removed second parameter from `Opis\Closure\SerializableClosure::from` method and from constructor
* Removed `Opis\Closure\{SecurityProviderInterface, DefaultSecurityProvider, SecureClosure}` classes
* Refactored how signed closures were handled
* Added `wrapClosures` and `unwrapClosures` static methods to `Opis\Closure\SerializableClosure` class
* Added `Opis\Colosure\serialize` and `Opis\Closure\unserialize` functions
* Improved serialization. You can now serialize arbitrary objects and the library will automatically wrap all closures
### v2.4.0, 2016.12.16
* The parser was refactored and improved
* Refactored `Opis\Closure\SerializableClosure::__invoke` method
* `Opis\Closure\{ISecurityProvider, SecurityProvider}` were added
* `Opis\Closure\{SecurityProviderInterface, DefaultSecurityProvider, SecureClosure}` were deprecated
and they will be removed in the next major version
* `setSecretKey` and `addSecurityProvider` static methods were added to `Opis\Closure\SerializableClosure`
### v2.3.2, 2016.12.15
* Fixed a bug that prevented namespace resolution to be done properly
### v2.3.1, 2016.12.13
* Hotfix. See [PR](https://github.com/opis/closure/pull/7)
### v2.3.0, 2016.11.17
* Added `isBindingRequired` and `isScopeRequired` to the `Opis\Closure\ReflectionClosure` class
* Automatically detects when the scope and/or the bound object of a closure needs to be serialized.
### v2.2.1, 2016.08.20
* Fixed a bug in `Opis\Closure\ReflectionClosure::fetchItems`
### v2.2.0, 2016.07.26
* Fixed CS
* `Opis\Closure\ClosureContext`, `Opis\Closure\ClosureScope`, `Opis\Closure\SelfReference`
and `Opis\Closure\SecurityException` classes were moved into separate files
* Added support for PHP7 syntax
* Fixed some bugs in `Opis\Closure\ReflectionClosure` class
* Improved closure parser
* Added an analyzer for SuperClosure library
### v2.1.0, 2015.09.30
* Added support for the missing `__METHOD__`, `__FUNCTION__` and `__TRAIT__` magic constants
* Added some security related classes and interfaces: `Opis\Closure\SecurityProviderInterface`,
`Opis\Closure\DefaultSecurityProvider`, `Opis\Closure\SecureClosure`, `Opis\Closure\SecurityException`.
* Fiexed a bug in `Opis\Closure\ReflectionClosure::getClasses` method
* Other minor bugfixes
* Added support for static closures
* Added public `isStatic` method to `Opis\Closure\ReflectionClosure` class
### v2.0.1, 2015.09.23
* Removed `branch-alias` property from `composer.json`
* Bugfix. See [issue #6](https://github.com/opis/closure/issues/6)
### v2.0.0, 2015.07.31
* The closure parser was improved
* Class names are now automatically resolved
* Added support for the `#trackme` directive which allows tracking closure's residing source
### v1.3.0, 2014.10.18
* Added autoload file
* Changed README file
### Opis Closure 1.2.2
* Started changelog

View File

@@ -1,20 +0,0 @@
The MIT License (MIT)
Copyright (c) 2018-2019 Zindex Software
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.

View File

@@ -1,9 +0,0 @@
Opis Closure
Copyright 2018-2019 Zindex Software
This product includes software developed at
Zindex Software (http://zindex.software).
This software was originally developed by Marius Sarca and Sorin Sarca
(Copyright 2014-2018). The copyright info was changed with the permission
of the original authors.

View File

@@ -1,92 +0,0 @@
Opis Closure
====================
[![Tests](https://github.com/opis/closure/workflows/Tests/badge.svg)](https://github.com/opis/closure/actions)
[![Latest Stable Version](https://poser.pugx.org/opis/closure/v/stable.png)](https://packagist.org/packages/opis/closure)
[![Latest Unstable Version](https://poser.pugx.org/opis/closure/v/unstable.png)](https://packagist.org/packages/opis/closure)
[![License](https://poser.pugx.org/opis/closure/license.png)](https://packagist.org/packages/opis/closure)
Serializable closures
---------------------
**Opis Closure** is a library that aims to overcome PHP's limitations regarding closure
serialization by providing a wrapper that will make all closures serializable.
**The library's key features:**
- Serialize any closure
- Serialize arbitrary objects
- Doesn't use `eval` for closure serialization or unserialization
- Works with any PHP version that has support for closures
- Supports PHP 7 syntax
- Handles all variables referenced/imported in `use()` and automatically wraps all referenced/imported closures for
proper serialization
- Handles recursive closures
- Handles magic constants like `__FILE__`, `__DIR__`, `__LINE__`, `__NAMESPACE__`, `__CLASS__`,
`__TRAIT__`, `__METHOD__` and `__FUNCTION__`.
- Automatically resolves all class names, function names and constant names used inside the closure
- Track closure's residing source by using the `#trackme` directive
- Simple and very fast parser
- Any error or exception, that might occur when executing an unserialized closure, can be caught and treated properly
- You can serialize/unserialize any closure unlimited times, even those previously unserialized
(this is possible because `eval()` is not used for unserialization)
- Handles static closures
- Supports cryptographically signed closures
- Provides a reflector that can give you information about the serialized closure
- Provides an analyzer for *SuperClosure* library
- Automatically detects when the scope and/or the bound object of a closure needs to be serialized
in order for the closure to work after deserialization
## Documentation
The full documentation for this library can be found [here][documentation].
## License
**Opis Closure** is licensed under the [MIT License (MIT)][license].
## Requirements
* PHP ^5.4 || ^7.0 || ^8.0
## Installation
**Opis Closure** is available on [Packagist] and it can be installed from a
command line interface by using [Composer].
```bash
composer require opis/closure
```
Or you could directly reference it into your `composer.json` file as a dependency
```json
{
"require": {
"opis/closure": "^3.5"
}
}
```
### Migrating from 2.x
If your project needs to support PHP 5.3 you can continue using the `2.x` version
of **Opis Closure**. Otherwise, assuming you are not using one of the removed/refactored classes or features(see
[CHANGELOG]), migrating to version `3.x` is simply a matter of updating your `composer.json` file.
### Semantic versioning
**Opis Closure** follows [semantic versioning][SemVer] specifications.
### Arbitrary object serialization
We've added this feature in order to be able to support the serialization of a closure's bound object.
The implementation is far from being perfect, and it's really hard to make it work flawless.
We will try to improve this, but we can't guarantee anything.
So our advice regarding the `Opis\Closure\serialize|unserialize` functions is to use them with caution.
[documentation]: https://www.opis.io/closure "Opis Closure"
[license]: http://opensource.org/licenses/MIT "MIT License"
[Packagist]: https://packagist.org/packages/opis/closure "Packagist"
[Composer]: https://getcomposer.org "Composer"
[SemVer]: http://semver.org/ "Semantic versioning"
[CHANGELOG]: https://github.com/opis/closure/blob/master/CHANGELOG.md "Changelog"

View File

@@ -1,39 +0,0 @@
<?php
/* ===========================================================================
* Copyright (c) 2018-2021 Zindex Software
*
* Licensed under the MIT License
* =========================================================================== */
require_once __DIR__ . '/functions.php';
spl_autoload_register(function($class){
$class = ltrim($class, '\\');
$dir = __DIR__ . '/src';
$namespace = 'Opis\Closure';
if(strpos($class, $namespace) === 0)
{
$class = substr($class, strlen($namespace));
$path = '';
if(($pos = strripos($class, '\\')) !== FALSE)
{
$path = str_replace('\\', '/', substr($class, 0, $pos)) . '/';
$class = substr($class, $pos + 1);
}
$path .= str_replace('_', '/', $class) . '.php';
$dir .= '/' . $path;
if(file_exists($dir))
{
include $dir;
return true;
}
return false;
}
return false;
});

View File

@@ -1,44 +0,0 @@
{
"name": "opis/closure",
"description": "A library that can be used to serialize closures (anonymous functions) and arbitrary objects.",
"keywords": ["closure", "serialization", "function", "serializable", "serialize", "anonymous functions"],
"homepage": "https://opis.io/closure",
"license": "MIT",
"authors": [
{
"name": "Marius Sarca",
"email": "marius.sarca@gmail.com"
},
{
"name": "Sorin Sarca",
"email": "sarca_sorin@hotmail.com"
}
],
"require": {
"php": "^5.4 || ^7.0 || ^8.0"
},
"require-dev": {
"jeremeamia/superclosure": "^2.0",
"phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0"
},
"autoload": {
"psr-4": {
"Opis\\Closure\\": "src/"
},
"files": ["functions.php"]
},
"autoload-dev": {
"psr-4": {
"Opis\\Closure\\Test\\": "tests/"
}
},
"extra": {
"branch-alias": {
"dev-master": "3.6.x-dev"
}
},
"config": {
"preferred-install": "dist",
"sort-packages": true
}
}

View File

@@ -1,41 +0,0 @@
<?php
/* ===========================================================================
* Copyright (c) 2018-2021 Zindex Software
*
* Licensed under the MIT License
* =========================================================================== */
namespace Opis\Closure;
/**
* Serialize
*
* @param mixed $data
* @return string
*/
function serialize($data)
{
SerializableClosure::enterContext();
SerializableClosure::wrapClosures($data);
$data = \serialize($data);
SerializableClosure::exitContext();
return $data;
}
/**
* Unserialize
*
* @param string $data
* @param array|null $options
* @return mixed
*/
function unserialize($data, array $options = null)
{
SerializableClosure::enterContext();
$data = ($options === null || \PHP_MAJOR_VERSION < 7)
? \unserialize($data)
: \unserialize($data, $options);
SerializableClosure::unwrapClosures($data);
SerializableClosure::exitContext();
return $data;
}

View File

@@ -1,62 +0,0 @@
<?php
/* ===========================================================================
* Copyright (c) 2018-2021 Zindex Software
*
* Licensed under the MIT License
* =========================================================================== */
namespace Opis\Closure;
use Closure;
use SuperClosure\Analyzer\ClosureAnalyzer;
/**
* @deprecated We'll remove this class
*/
class Analyzer extends ClosureAnalyzer
{
/**
* Analyzer a given closure.
*
* @param Closure $closure
*
* @return array
*/
public function analyze(Closure $closure)
{
$reflection = new ReflectionClosure($closure);
$scope = $reflection->getClosureScopeClass();
$data = [
'reflection' => $reflection,
'code' => $reflection->getCode(),
'hasThis' => $reflection->isBindingRequired(),
'context' => $reflection->getUseVariables(),
'hasRefs' => false,
'binding' => $reflection->getClosureThis(),
'scope' => $scope ? $scope->getName() : null,
'isStatic' => $reflection->isStatic(),
];
return $data;
}
/**
* @param array $data
* @return mixed
*/
protected function determineCode(array &$data)
{
return null;
}
/**
* @param array $data
* @return mixed
*/
protected function determineContext(array &$data)
{
return null;
}
}

View File

@@ -1,34 +0,0 @@
<?php
/* ===========================================================================
* Copyright (c) 2018-2021 Zindex Software
*
* Licensed under the MIT License
* =========================================================================== */
namespace Opis\Closure;
/**
* Closure context class
* @internal
*/
class ClosureContext
{
/**
* @var ClosureScope Closures scope
*/
public $scope;
/**
* @var integer
*/
public $locks;
/**
* Constructor
*/
public function __construct()
{
$this->scope = new ClosureScope();
$this->locks = 0;
}
}

View File

@@ -1,25 +0,0 @@
<?php
/* ===========================================================================
* Copyright (c) 2018-2021 Zindex Software
*
* Licensed under the MIT License
* =========================================================================== */
namespace Opis\Closure;
/**
* Closure scope class
* @internal
*/
class ClosureScope extends \SplObjectStorage
{
/**
* @var integer Number of serializations in current scope
*/
public $serializations = 0;
/**
* @var integer Number of closures that have to be serialized
*/
public $toserialize = 0;
}

View File

@@ -1,99 +0,0 @@
<?php
/* ===========================================================================
* Copyright (c) 2018-2021 Zindex Software
*
* Licensed under the MIT License
* =========================================================================== */
namespace Opis\Closure;
/**
* @internal
*/
class ClosureStream
{
const STREAM_PROTO = 'closure';
protected static $isRegistered = false;
protected $content;
protected $length;
protected $pointer = 0;
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;
}
public function stream_read($count)
{
$value = substr($this->content, $this->pointer, $count);
$this->pointer += $count;
return $value;
}
public function stream_eof()
{
return $this->pointer >= $this->length;
}
public function stream_set_option($option, $arg1, $arg2)
{
return false;
}
public function stream_stat()
{
$stat = stat(__FILE__);
$stat[7] = $stat['size'] = $this->length;
return $stat;
}
public function url_stat($path, $flags)
{
$stat = stat(__FILE__);
$stat[7] = $stat['size'] = $this->length;
return $stat;
}
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;
}
public function stream_tell()
{
return $this->pointer;
}
public static function register()
{
if (!static::$isRegistered) {
static::$isRegistered = stream_wrapper_register(static::STREAM_PROTO, __CLASS__);
}
}
}

View File

@@ -1,25 +0,0 @@
<?php
/* ===========================================================================
* Copyright (c) 2018-2021 Zindex Software
*
* Licensed under the MIT License
* =========================================================================== */
namespace Opis\Closure;
interface ISecurityProvider
{
/**
* Sign serialized closure
* @param string $closure
* @return array
*/
public function sign($closure);
/**
* Verify signature
* @param array $data
* @return bool
*/
public function verify(array $data);
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,18 +0,0 @@
<?php
/* ===========================================================================
* Copyright (c) 2018-2021 Zindex Software
*
* Licensed under the MIT License
* =========================================================================== */
namespace Opis\Closure;
use Exception;
/**
* Security exception class
*/
class SecurityException extends Exception
{
}

View File

@@ -1,42 +0,0 @@
<?php
/* ===========================================================================
* Copyright (c) 2018-2021 Zindex Software
*
* Licensed under the MIT License
* =========================================================================== */
namespace Opis\Closure;
class SecurityProvider implements ISecurityProvider
{
/** @var string */
protected $secret;
/**
* SecurityProvider constructor.
* @param string $secret
*/
public function __construct($secret)
{
$this->secret = $secret;
}
/**
* @inheritdoc
*/
public function sign($closure)
{
return array(
'closure' => $closure,
'hash' => base64_encode(hash_hmac('sha256', $closure, $this->secret, true)),
);
}
/**
* @inheritdoc
*/
public function verify(array $data)
{
return base64_encode(hash_hmac('sha256', $data['closure'], $this->secret, true)) === $data['hash'];
}
}

View File

@@ -1,31 +0,0 @@
<?php
/* ===========================================================================
* Copyright (c) 2018-2021 Zindex Software
*
* Licensed under the MIT License
* =========================================================================== */
namespace Opis\Closure;
/**
* Helper class used to indicate a reference to an object
* @internal
*/
class SelfReference
{
/**
* @var string An unique hash representing the object
*/
public $hash;
/**
* Constructor
*
* @param string $hash
*/
public function __construct($hash)
{
$this->hash = $hash;
}
}

View File

@@ -1,678 +0,0 @@
<?php
/* ===========================================================================
* Copyright (c) 2018-2021 Zindex Software
*
* Licensed under the MIT License
* =========================================================================== */
namespace Opis\Closure;
use Closure;
use Serializable;
use SplObjectStorage;
use ReflectionObject;
/**
* Provides a wrapper for serialization of closures
*/
class SerializableClosure implements Serializable
{
/**
* @var Closure Wrapped closure
*
* @see \Opis\Closure\SerializableClosure::getClosure()
*/
protected $closure;
/**
* @var ReflectionClosure A reflection instance for closure
*
* @see \Opis\Closure\SerializableClosure::getReflector()
*/
protected $reflector;
/**
* @var mixed Used at deserialization to hold variables
*
* @see \Opis\Closure\SerializableClosure::unserialize()
* @see \Opis\Closure\SerializableClosure::getReflector()
*/
protected $code;
/**
* @var string Closure's ID
*/
protected $reference;
/**
* @var string Closure scope
*/
protected $scope;
/**
* @var ClosureContext Context of closure, used in serialization
*/
protected static $context;
/**
* @var ISecurityProvider|null
*/
protected static $securityProvider;
/** Array recursive constant*/
const ARRAY_RECURSIVE_KEY = '¯\_(ツ)_/¯';
/**
* Constructor
*
* @param Closure $closure Closure you want to serialize
*/
public function __construct(Closure $closure)
{
$this->closure = $closure;
if (static::$context !== null) {
$this->scope = static::$context->scope;
$this->scope->toserialize++;
}
}
/**
* Get the Closure object
*
* @return Closure The wrapped closure
*/
public function getClosure()
{
return $this->closure;
}
/**
* Get the reflector for closure
*
* @return ReflectionClosure
*/
public function getReflector()
{
if ($this->reflector === null) {
$this->reflector = new ReflectionClosure($this->closure);
$this->code = null;
}
return $this->reflector;
}
/**
* Implementation of magic method __invoke()
*/
public function __invoke()
{
return call_user_func_array($this->closure, func_get_args());
}
/**
* Implementation of Serializable::serialize()
*
* @return string The serialized closure
*/
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;
}
} else {
if($scope = $reflector->getClosureScopeClass()){
$scope = $scope->name;
}
}
$this->reference = spl_object_hash($this->closure);
$this->scope[$this->closure] = $this;
$use = $this->transformUseVariables($reflector->getUseVariables());
$code = $reflector->getCode();
$this->mapByReference($use);
$ret = \serialize(array(
'use' => $use,
'function' => $code,
'scope' => $scope,
'this' => $object,
'self' => $this->reference,
));
if (static::$securityProvider !== null) {
$data = static::$securityProvider->sign($ret);
$ret = '@' . $data['hash'] . '.' . $data['closure'];
}
if (!--$this->scope->serializations && !--$this->scope->toserialize) {
$this->scope = null;
}
return $ret;
}
/**
* Transform the use variables before serialization.
*
* @param array $data The Closure's use variables
* @return array
*/
protected function transformUseVariables($data)
{
return $data;
}
/**
* Implementation of Serializable::unserialize()
*
* @param string $data Serialized data
* @throws SecurityException
*/
public function unserialize($data)
{
ClosureStream::register();
if (static::$securityProvider !== null) {
if ($data[0] !== '@') {
throw new SecurityException("The serialized closure is not signed. ".
"Make sure you use a security provider for both serialization and unserialization.");
}
if ($data[1] !== '{') {
$separator = strpos($data, '.');
if ($separator === false) {
throw new SecurityException('Invalid signed closure');
}
$hash = substr($data, 1, $separator - 1);
$closure = substr($data, $separator + 1);
$data = ['hash' => $hash, 'closure' => $closure];
unset($hash, $closure);
} else {
$data = json_decode(substr($data, 1), true);
}
if (!is_array($data) || !static::$securityProvider->verify($data)) {
throw new SecurityException("Your serialized closure might have been modified and it's unsafe to be unserialized. " .
"Make sure you use the same security provider, with the same settings, " .
"both for serialization and unserialization.");
}
$data = $data['closure'];
} elseif ($data[0] === '@') {
if ($data[1] !== '{') {
$separator = strpos($data, '.');
if ($separator === false) {
throw new SecurityException('Invalid signed closure');
}
$hash = substr($data, 1, $separator - 1);
$closure = substr($data, $separator + 1);
$data = ['hash' => $hash, 'closure' => $closure];
unset($hash, $closure);
} else {
$data = json_decode(substr($data, 1), true);
}
if (!is_array($data) || !isset($data['closure']) || !isset($data['hash'])) {
throw new SecurityException('Invalid signed closure');
}
$data = $data['closure'];
}
$this->code = \unserialize($data);
// unset data
unset($data);
$this->code['objects'] = array();
if ($this->code['use']) {
$this->scope = new ClosureScope();
$this->code['use'] = $this->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'];
}
/**
* Resolve the use variables after unserialization.
*
* @param array $data The Closure's transformed use variables
* @return array
*/
protected function resolveUseVariables($data)
{
return $data;
}
/**
* Wraps a closure and sets the serialization context (if any)
*
* @param Closure $closure Closure to be wrapped
*
* @return self The wrapped closure
*/
public static function from(Closure $closure)
{
if (static::$context === null) {
$instance = new static($closure);
} elseif (isset(static::$context->scope[$closure])) {
$instance = static::$context->scope[$closure];
} else {
$instance = new static($closure);
static::$context->scope[$closure] = $instance;
}
return $instance;
}
/**
* Increments the context lock counter or creates a new context if none exist
*/
public static function enterContext()
{
if (static::$context === null) {
static::$context = new ClosureContext();
}
static::$context->locks++;
}
/**
* Decrements the context lock counter and destroy the context when it reaches to 0
*/
public static function exitContext()
{
if (static::$context !== null && !--static::$context->locks) {
static::$context = null;
}
}
/**
* @param string $secret
*/
public static function setSecretKey($secret)
{
if(static::$securityProvider === null){
static::$securityProvider = new SecurityProvider($secret);
}
}
/**
* @param ISecurityProvider $securityProvider
*/
public static function addSecurityProvider(ISecurityProvider $securityProvider)
{
static::$securityProvider = $securityProvider;
}
/**
* Remove security provider
*/
public static function removeSecurityProvider()
{
static::$securityProvider = null;
}
/**
* @return null|ISecurityProvider
*/
public static function getSecurityProvider()
{
return static::$securityProvider;
}
/**
* Wrap closures
*
* @internal
* @param $data
* @param ClosureScope|SplObjectStorage|null $storage
*/
public static function wrapClosures(&$data, SplObjectStorage $storage = null)
{
if($storage === null){
$storage = static::$context->scope;
}
if($data instanceof Closure){
$data = static::from($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){
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());
}
}
/**
* Unwrap closures
*
* @internal
* @param $data
* @param SplObjectStorage|null $storage
*/
public static function unwrapClosures(&$data, SplObjectStorage $storage = null)
{
if($storage === null){
$storage = static::$context->scope;
}
if($data instanceof static){
$data = $data->getClosure();
} 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::unwrapClosures($value, $storage);
}
unset($data[self::ARRAY_RECURSIVE_KEY]);
}elseif ($data instanceof \stdClass){
if(isset($storage[$data])){
return;
}
$storage[$data] = true;
foreach ($data as &$property){
static::unwrapClosures($property, $storage);
}
} elseif (is_object($data) && !($data instanceof Closure)){
if(isset($storage[$data])){
return;
}
$storage[$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;
}
$value = $property->getValue($data);
if(is_array($value) || is_object($value)){
static::unwrapClosures($value, $storage);
$property->setValue($data, $value);
}
};
} while($reflection = $reflection->getParentClass());
}
}
/**
* Creates a new closure from arbitrary code,
* emulating create_function, but without using eval
*
* @param string$args
* @param string $code
* @return Closure
*/
public static function createClosure($args, $code)
{
ClosureStream::register();
return include(ClosureStream::STREAM_PROTO . '://function(' . $args. '){' . $code . '};');
}
/**
* Internal method used to map closure pointers
* @internal
* @param $data
*/
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;
}
$item = $property->getValue($data);
if ($item instanceof SerializableClosure || ($item instanceof SelfReference && $item->hash === $this->code['self'])) {
$this->code['objects'][] = array(
'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
*
* @internal
* @param mixed &$data
*/
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);
if (static::$context !== null) {
static::$context->scope->toserialize--;
} else {
$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){
if(isset($this->scope[$data])){
$data = $this->scope[$data];
return;
}
$instance = $data;
$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;
}
$value = $property->getValue($instance);
if(is_array($value) || is_object($value)){
$this->mapByReference($value);
}
$property->setValue($data, $value);
}
} while($reflection = $reflection->getParentClass());
}
}
}

View File

@@ -46,9 +46,11 @@ class ArrayLoader implements LoaderInterface
foreach ($messages as $key => $value) {
if (\is_array($value)) {
foreach ($this->flatten($value) as $k => $v) {
$result[$key.'.'.$k] = $v;
if (null !== $v) {
$result[$key.'.'.$k] = $v;
}
}
} else {
} elseif (null !== $value) {
$result[$key] = $value;
}
}

View File

@@ -1,201 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -1,87 +0,0 @@
# think-cache
用于PHP缓存管理PHP 7.1+),支持`PSR-6``PSR-16`缓存规范。
主要特性包括:
* 支持多缓存通道设置及切换
* 支持缓存数据递增/递减
* 支持门面调用
* 内置File/Redis/Memcache/Memcached/Wincache
* 支持缓存标签
* 支持闭包数据
* 支持`PSR-6``PSR-16`缓存规范
## 安装
~~~
composer require topthink/think-cache
~~~
## 用法:
~~~php
use think\facade\Cache;
// 缓存配置
Cache::config([
'default' => 'file',
'stores' => [
'file' => [
'type' => 'File',
// 缓存保存目录
'path' => './cache/',
// 缓存前缀
'prefix' => '',
// 缓存有效期 0表示永久缓存
'expire' => 0,
],
'redis' => [
'type' => 'redis',
'host' => '127.0.0.1',
'port' => 6379,
'prefix' => '',
'expire' => 0,
],
],
]);
// 设置缓存
Cache::set('val','value',600);
// 判断缓存是否设置
Cache::has('val');
// 获取缓存
Cache::get('val');
// 删除缓存
Cache::delete('val');
// 清除缓存
Cache::clear();
// 读取并删除缓存
Cache::pull('val');
// 不存在则写入
Cache::remember('val',10);
// 对于数值类型的缓存数据可以使用
// 缓存增+1
Cache::inc('val');
// 缓存增+5
Cache::inc('val',5);
// 缓存减1
Cache::dec('val');
// 缓存减5
Cache::dec('val',5);
// 使用缓存标签
Cache::tag('tag_name')->set('val','value',600);
// 删除某个标签下的缓存数据
Cache::tag('tag_name')->clear();
// 支持指定多个标签
Cache::tag(['tag1','tag2'])->set('val2','value',600);
// 删除多个标签下的缓存数据
Cache::tag(['tag1','tag2'])->clear();
// 使用多种缓存类型
$redis = Cache::store('redis');
$redis->set('var','value',600);
$redis->get('var');
~~~
更多内容可以参考 https://www.kancloud.cn/manual/thinkphp6_0/1037634

View File

@@ -1,24 +0,0 @@
{
"name": "topthink/think-cache",
"description": "Cache Manager",
"license": "Apache-2.0",
"authors": [
{
"name": "liu21st",
"email": "liu21st@gmail.com"
}
],
"require": {
"php": ">=7.1.0",
"psr/cache": "~1.0",
"topthink/think-container": "~2.0",
"psr/simple-cache": "^1.0",
"opis/closure": "^3.1"
},
"autoload": {
"psr-4": {
"think\\": "src"
},
"files": []
}
}

View File

@@ -1,273 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2019 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
declare (strict_types = 1);
namespace think;
use Psr\Cache\CacheItemInterface;
use Psr\Cache\CacheItemPoolInterface;
use think\cache\Driver;
use think\Container;
use think\exception\InvalidArgumentException;
use think\cache\CacheItem;
/**
* 缓存管理类
* @mixin Driver
*/
class CacheManager implements CacheItemPoolInterface
{
/**
* 缓存队列
* @var array
*/
protected $data = [];
/**
* 延期保存的缓存队列
* @var array
*/
protected $deferred = [];
/**
* 缓存实例
* @var array
*/
protected $instance = [];
/**
* 配置参数
* @var array
*/
protected $config = [];
/**
* 初始化
* @access public
* @param array $config 配置参数
* @return $this
*/
public function init(array $config = [])
{
$this->config = $config;
return $this;
}
/**
* 连接或者切换缓存
* @access public
* @param string $name 连接配置名
* @param bool $force 强制重新连接
* @return Driver
*/
public function store(string $name = '', bool $force = false): Driver
{
if ('' == $name) {
$name = $this->config['default'] ?? 'file';
}
if ($force || !isset($this->instance[$name])) {
if (!isset($this->config['stores'][$name])) {
throw new InvalidArgumentException('Undefined cache config:' . $name);
}
$options = $this->config['stores'][$name];
$this->instance[$name] = $this->connect($options);
}
return $this->instance[$name];
}
/**
* 连接缓存
* @access public
* @param array $options 连接参数
* @param string $name 连接配置名
* @return Driver
*/
public function connect(array $options, string $name = ''): Driver
{
if ($name && isset($this->instance[$name])) {
return $this->instance[$name];
}
$type = !empty($options['type']) ? $options['type'] : 'File';
$handler = Container::factory($type, '\\think\\cache\\driver\\', $options);
if ($name) {
$this->instance[$name] = $handler;
}
return $handler;
}
/**
* 设置配置
* @access public
* @param array $config 配置参数
* @return void
*/
public function config(array $config): void
{
$this->config = array_merge($this->config, $config);
}
/**
* 返回「键」对应的一个缓存项。
* @access public
* @param string $key 缓存标识
* @return CacheItemInterface
* @throws InvalidArgumentException
*/
public function getItem($key): CacheItem
{
if (isset($this->data[$key])) {
return $this->data[$key];
}
$cacheItem = new CacheItem($key);
if ($this->has($key)) {
$cacheItem->set($this->get($key));
}
$this->data[$key] = $cacheItem;
return $cacheItem;
}
/**
* 返回一个可供遍历的缓存项集合。
* @access public
* @param array $keys
* @return array|\Traversable
* @throws InvalidArgumentException
*/
public function getItems(array $keys = []): array
{
$result = [];
foreach ($keys as $key) {
$result[] = $this->getItem($key);
}
return $result;
}
/**
* 检查缓存系统中是否有「键」对应的缓存项。
* @access public
* @param string $key
* @return bool
* @throws InvalidArgumentException
*/
public function hasItem($key): bool
{
return $this->store()->has($key);
}
/**
* 清空缓冲池
* @access public
* @return bool
*/
public function clear(): bool
{
return $this->store()->clear();
}
/**
* 从缓冲池里移除某个缓存项
* @access public
* @param string $key
* @return bool
* @throws InvalidArgumentException
*/
public function deleteItem($key): bool
{
return $this->store()->delete($key);
}
/**
* 从缓冲池里移除多个缓存项
* @access public
* @param array $keys
* @return bool
* @throws InvalidArgumentException
*/
public function deleteItems(array $keys): bool
{
foreach ($keys as $key) {
$this->store()->delete($key);
}
return true;
}
/**
* 立刻为「CacheItemInterface」对象做数据持久化。
* @access public
* @param CacheItemInterface $item
* @return bool
*/
public function save(CacheItemInterface $item): bool
{
if ($item->getKey()) {
return $this->store()->set($item->getKey(), $item->get(), $item->getExpire());
}
return false;
}
/**
* 稍后为「CacheItemInterface」对象做数据持久化。
* @access public
* @param CacheItemInterface $item
* @return bool
*/
public function saveDeferred(CacheItemInterface $item): bool
{
$this->deferred[$item->getKey()] = $item;
return true;
}
/**
* 提交所有的正在队列里等待的请求到数据持久层,配合 `saveDeferred()` 使用
* @access public
* @return bool
*/
public function commit(): bool
{
foreach ($this->deferred as $key => $item) {
$result = $this->save($item);
unset($this->deferred[$key]);
if (false === $result) {
return false;
}
}
return true;
}
public function __call($method, $args)
{
return call_user_func_array([$this->store(), $method], $args);
}
public function __destruct()
{
if (!empty($this->deferred)) {
$this->commit();
}
}
}

View File

@@ -1,210 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2019 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
declare (strict_types = 1);
namespace think\cache;
use DateInterval;
use DateTime;
use DateTimeInterface;
use Psr\Cache\CacheItemInterface;
use think\cache\exception\InvalidArgumentException;
/**
* CacheItem实现类
*/
class CacheItem implements CacheItemInterface
{
/**
* 缓存Key
* @var string
*/
protected $key;
/**
* 缓存内容
* @var mixed
*/
protected $value;
/**
* 过期时间
* @var int|DateTimeInterface
*/
protected $expire;
/**
* 缓存tag
* @var string
*/
protected $tag;
/**
* 缓存是否命中
* @var bool
*/
protected $isHit = false;
public function __construct(string $key = null)
{
$this->key = $key;
}
/**
* 为此缓存项设置「键」
* @access public
* @param string $key
* @return $this
*/
public function setKey(string $key)
{
$this->key = $key;
return $this;
}
/**
* 返回当前缓存项的「键」
* @access public
* @return string
*/
public function getKey()
{
return $this->key;
}
/**
* 返回当前缓存项的有效期
* @access public
* @return DateTimeInterface|int|null
*/
public function getExpire()
{
if ($this->expire instanceof DateTimeInterface) {
return $this->expire;
}
return $this->expire ? $this->expire - time() : null;
}
/**
* 获取缓存Tag
* @access public
* @return string
*/
public function getTag()
{
return $this->tag;
}
/**
* 凭借此缓存项的「键」从缓存系统里面取出缓存项
* @access public
* @return mixed
*/
public function get()
{
return $this->value;
}
/**
* 确认缓存项的检查是否命中
* @access public
* @return bool
*/
public function isHit(): bool
{
return $this->isHit;
}
/**
* 为此缓存项设置「值」
* @access public
* @param mixed $value
* @return $this
*/
public function set($value)
{
$this->value = $value;
$this->isHit = true;
return $this;
}
/**
* 为此缓存项设置所属标签
* @access public
* @param string $tag
* @return $this
*/
public function tag(string $tag = null)
{
$this->tag = $tag;
return $this;
}
/**
* 设置缓存项的有效期
* @access public
* @param mixed $expire
* @return $this
*/
public function expire($expire)
{
if (is_null($expire)) {
$this->expire = null;
} elseif (is_numeric($expire) || $expire instanceof DateInterval) {
$this->expiresAfter($expire);
} elseif ($expire instanceof DateTimeInterface) {
$this->expire = $expire;
} else {
throw new InvalidArgumentException('not support datetime');
}
return $this;
}
/**
* 设置缓存项的准确过期时间点
* @access public
* @param DateTimeInterface $expiration
* @return $this
*/
public function expiresAt($expiration)
{
if ($expiration instanceof DateTimeInterface) {
$this->expire = $expiration;
} else {
throw new InvalidArgumentException('not support datetime');
}
return $this;
}
/**
* 设置缓存项的过期时间
* @access public
* @param int|DateInterval $timeInterval
* @return $this
* @throws InvalidArgumentException
*/
public function expiresAfter($timeInterval)
{
if ($timeInterval instanceof DateInterval) {
$this->expire = (int) DateTime::createFromFormat('U', (string) time())->add($timeInterval)->format('U');
} elseif (is_numeric($timeInterval)) {
$this->expire = $timeInterval + time();
} else {
throw new InvalidArgumentException('not support datetime');
}
return $this;
}
}

View File

@@ -1,349 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2019 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
declare (strict_types = 1);
namespace think\cache;
use DateInterval;
use DateTime;
use DateTimeInterface;
use Opis\Closure\SerializableClosure;
use Psr\SimpleCache\CacheInterface;
use think\exception\InvalidArgumentException;
use think\Container;
/**
* 缓存基础类
*/
abstract class Driver implements CacheInterface
{
/**
* 驱动句柄
* @var object
*/
protected $handler = null;
/**
* 缓存读取次数
* @var integer
*/
protected $readTimes = 0;
/**
* 缓存写入次数
* @var integer
*/
protected $writeTimes = 0;
/**
* 缓存参数
* @var array
*/
protected $options = [];
/**
* 缓存标签
* @var array
*/
protected $tag = [];
/**
* 获取有效期
* @access protected
* @param integer|DateTimeInterface|DateInterval $expire 有效期
* @return int
*/
protected function getExpireTime($expire): int
{
if ($expire instanceof DateTimeInterface) {
$expire = $expire->getTimestamp() - time();
} elseif ($expire instanceof DateInterval) {
$expire = DateTime::createFromFormat('U', (string) time())
->add($expire)
->format('U') - time();
}
return (int) $expire;
}
/**
* 获取实际的缓存标识
* @access public
* @param string $name 缓存名
* @return string
*/
public function getCacheKey(string $name): string
{
return $this->options['prefix'] . $name;
}
/**
* 读取缓存并删除
* @access public
* @param string $name 缓存变量名
* @return mixed
*/
public function pull(string $name)
{
$result = $this->get($name, false);
if ($result) {
$this->delete($name);
return $result;
}
}
/**
* 追加(数组)缓存
* @access public
* @param string $name 缓存变量名
* @param mixed $value 存储数据
* @return void
*/
public function push(string $name, $value): void
{
$item = $this->get($name, []);
if (!is_array($item)) {
throw new InvalidArgumentException('only array cache can be push');
}
$item[] = $value;
if (count($item) > 1000) {
array_shift($item);
}
$item = array_unique($item);
$this->set($name, $item);
}
/**
* 如果不存在则写入缓存
* @access public
* @param string $name 缓存变量名
* @param mixed $value 存储数据
* @param int $expire 有效时间 0为永久
* @return mixed
*/
public function remember(string $name, $value, $expire = null)
{
if ($this->has($name)) {
return $this->get($name);
}
$time = time();
while ($time + 5 > time() && $this->has($name . '_lock')) {
// 存在锁定则等待
usleep(200000);
}
try {
// 锁定
$this->set($name . '_lock', true);
if ($value instanceof \Closure) {
// 获取缓存数据
$value = Container::getInstance()->invokeFunction($value);
}
// 缓存数据
$this->set($name, $value, $expire);
// 解锁
$this->delete($name . '_lock');
} catch (\Exception | \throwable $e) {
$this->delete($name . '_lock');
throw $e;
}
return $value;
}
/**
* 缓存标签
* @access public
* @param string|array $name 标签名
* @return $this
*/
public function tag($name)
{
$name = (array) $name;
$key = implode('-', $name);
if (!isset($this->tag[$key])) {
$name = array_map(function ($val) {
return $this->getTagKey($val);
}, $name);
$this->tag[$key] = new TagSet($name, $this);
}
return $this->tag[$key];
}
/**
* 获取标签包含的缓存标识
* @access public
* @param string $tag 标签标识
* @return array
*/
public function getTagItems(string $tag): array
{
$name = $this->getTagKey($tag);
return $this->get($name, []);
}
/**
* 获取实际标签名
* @access public
* @param string $tag 标签名
* @return string
*/
public function getTagKey(string $tag): string
{
return $this->options['tag_prefix'] . md5($tag);
}
/**
* 序列化数据
* @access protected
* @param mixed $data 缓存数据
* @return string
*/
protected function serialize($data): string
{
$serialize = $this->options['serialize'][0] ?? function ($data) {
SerializableClosure::enterContext();
SerializableClosure::wrapClosures($data);
$data = \serialize($data);
SerializableClosure::exitContext();
return $data;
};
return $serialize($data);
}
/**
* 反序列化数据
* @access protected
* @param string $data 缓存数据
* @return mixed
*/
protected function unserialize(string $data)
{
$unserialize = $this->options['serialize'][1] ?? function ($data) {
SerializableClosure::enterContext();
$data = \unserialize($data);
SerializableClosure::unwrapClosures($data);
SerializableClosure::exitContext();
return $data;
};
return $unserialize($data);
}
/**
* 返回句柄对象,可执行其它高级方法
*
* @access public
* @return object
*/
public function handler()
{
return $this->handler;
}
/**
* 返回缓存读取次数
* @access public
* @return int
*/
public function getReadTimes(): int
{
return $this->readTimes;
}
/**
* 返回缓存写入次数
* @access public
* @return int
*/
public function getWriteTimes(): int
{
return $this->writeTimes;
}
/**
* 读取缓存
* @access public
* @param iterable $keys 缓存变量名
* @param mixed $default 默认值
* @return iterable
* @throws InvalidArgumentException
*/
public function getMultiple($keys, $default = null): iterable
{
$result = [];
foreach ($keys as $key) {
$result[$key] = $this->get($key, $default);
}
return $result;
}
/**
* 写入缓存
* @access public
* @param iterable $values 缓存数据
* @param null|int|\DateInterval $ttl 有效时间 0为永久
* @return bool
*/
public function setMultiple($values, $ttl = null): bool
{
foreach ($values as $key => $val) {
$result = $this->set($key, $val, $ttl);
if (false === $result) {
return false;
}
}
return true;
}
/**
* 删除缓存
* @access public
* @param iterable $keys 缓存变量名
* @return bool
* @throws InvalidArgumentException
*/
public function deleteMultiple($keys): bool
{
foreach ($keys as $key) {
$result = $this->delete($key);
if (false === $result) {
return false;
}
}
return true;
}
public function __call($method, $args)
{
return call_user_func_array([$this->handler, $method], $args);
}
}

View File

@@ -1,130 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2019 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
declare (strict_types = 1);
namespace think\cache;
/**
* 标签集合
*/
class TagSet
{
/**
* 标签的缓存Key
* @var array
*/
protected $tag;
/**
* 缓存句柄
* @var Driver
*/
protected $handler;
/**
* 架构函数
* @access public
* @param array $tag 缓存标签
* @param Driver $cache 缓存对象
*/
public function __construct(array $tag, Driver $cache)
{
$this->tag = $tag;
$this->handler = $cache;
}
/**
* 写入缓存
* @access public
* @param string $name 缓存变量名
* @param mixed $value 存储数据
* @param integer|\DateTime $expire 有效时间(秒)
* @return bool
*/
public function set($name, $value, $expire = null): bool
{
$this->handler->set($name, $value, $expire);
$this->append($name);
return true;
}
/**
* 追加缓存标识到标签
* @access public
* @param string $name 缓存变量名
* @return void
*/
public function append(string $name): void
{
$name = $this->handler->getCacheKey($name);
foreach ($this->tag as $tag) {
$this->handler->push($tag, $name);
}
}
/**
* 写入缓存
* @access public
* @param iterable $values 缓存数据
* @param null|int|\DateInterval $ttl 有效时间 0为永久
* @return bool
*/
public function setMultiple($values, $ttl = null): bool
{
foreach ($values as $key => $val) {
$result = $this->set($key, $val, $ttl);
if (false === $result) {
return false;
}
}
return true;
}
/**
* 如果不存在则写入缓存
* @access public
* @param string $name 缓存变量名
* @param mixed $value 存储数据
* @param int $expire 有效时间 0为永久
* @return mixed
*/
public function remember(string $name, $value, $expire = null)
{
$result = $this->handler->remember($name, $value, $expire);
$this->append($name);
return $result;
}
/**
* 清除缓存
* @access public
* @return bool
*/
public function clear(): bool
{
// 指定标签清除
foreach ($this->tag as $tag) {
$names = $this->handler->get($tag, []);
$this->handler->clearTag($names);
$this->handler->delete($tag);
}
return true;
}
}

View File

@@ -1,286 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2019 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
declare (strict_types = 1);
namespace think\cache\driver;
use think\cache\Driver;
/**
* 文件缓存类
*/
class File extends Driver
{
/**
* 配置参数
* @var array
*/
protected $options = [
'expire' => 0,
'cache_subdir' => true,
'prefix' => '',
'path' => '',
'hash_type' => 'md5',
'data_compress' => false,
'tag_prefix' => 'tag:',
'serialize' => [],
];
/**
* 有效期
* @var int|\DateTime
*/
protected $expire;
/**
* 架构函数
* @param array $options 参数
*/
public function __construct(array $options = [])
{
if (!empty($options)) {
$this->options = array_merge($this->options, $options);
}
if (substr($this->options['path'], -1) != DIRECTORY_SEPARATOR) {
$this->options['path'] .= DIRECTORY_SEPARATOR;
}
}
/**
* 取得变量的存储文件名
* @access public
* @param string $name 缓存变量名
* @return string
*/
public function getCacheKey(string $name): string
{
$name = hash($this->options['hash_type'], $name);
if ($this->options['cache_subdir']) {
// 使用子目录
$name = substr($name, 0, 2) . DIRECTORY_SEPARATOR . substr($name, 2);
}
if ($this->options['prefix']) {
$name = $this->options['prefix'] . DIRECTORY_SEPARATOR . $name;
}
return $this->options['path'] . $name . '.php';
}
/**
* 判断缓存是否存在
* @access public
* @param string $name 缓存变量名
* @return bool
*/
public function has($name): bool
{
return false !== $this->get($name) ? true : false;
}
/**
* 读取缓存
* @access public
* @param string $name 缓存变量名
* @param mixed $default 默认值
* @return mixed
*/
public function get($name, $default = null)
{
$this->readTimes++;
$filename = $this->getCacheKey($name);
if (!is_file($filename)) {
return $default;
}
$content = file_get_contents($filename);
$this->expire = null;
if (false !== $content) {
$expire = (int) substr($content, 8, 12);
if (0 != $expire && time() > filemtime($filename) + $expire) {
//缓存过期删除缓存文件
$this->unlink($filename);
return $default;
}
$this->expire = $expire;
$content = substr($content, 32);
if ($this->options['data_compress'] && function_exists('gzcompress')) {
//启用数据压缩
$content = gzuncompress($content);
}
return $this->unserialize($content);
} else {
return $default;
}
}
/**
* 写入缓存
* @access public
* @param string $name 缓存变量名
* @param mixed $value 存储数据
* @param int|\DateTime $expire 有效时间 0为永久
* @return bool
*/
public function set($name, $value, $expire = null): bool
{
$this->writeTimes++;
if (is_null($expire)) {
$expire = $this->options['expire'];
}
$expire = $this->getExpireTime($expire);
$filename = $this->getCacheKey($name);
$dir = dirname($filename);
if (!is_dir($dir)) {
try {
mkdir($dir, 0755, true);
} catch (\Exception $e) {
// 创建失败
}
}
$data = $this->serialize($value);
if ($this->options['data_compress'] && function_exists('gzcompress')) {
//数据压缩
$data = gzcompress($data, 3);
}
$data = "<?php\n//" . sprintf('%012d', $expire) . "\n exit();?>\n" . $data;
$result = file_put_contents($filename, $data);
if ($result) {
clearstatcache();
return true;
}
return false;
}
/**
* 自增缓存(针对数值缓存)
* @access public
* @param string $name 缓存变量名
* @param int $step 步长
* @return false|int
*/
public function inc(string $name, int $step = 1)
{
if ($this->has($name)) {
$value = $this->get($name) + $step;
$expire = $this->expire;
} else {
$value = $step;
$expire = 0;
}
return $this->set($name, $value, $expire) ? $value : false;
}
/**
* 自减缓存(针对数值缓存)
* @access public
* @param string $name 缓存变量名
* @param int $step 步长
* @return false|int
*/
public function dec(string $name, int $step = 1)
{
if ($this->has($name)) {
$value = $this->get($name) - $step;
$expire = $this->expire;
} else {
$value = -$step;
$expire = 0;
}
return $this->set($name, $value, $expire) ? $value : false;
}
/**
* 删除缓存
* @access public
* @param string $name 缓存变量名
* @return bool
*/
public function delete($name): bool
{
$this->writeTimes++;
try {
return $this->unlink($this->getCacheKey($name));
} catch (\Exception $e) {
return false;
}
}
/**
* 清除缓存
* @access public
* @return bool
*/
public function clear(): bool
{
$this->writeTimes++;
$files = (array) glob($this->options['path'] . ($this->options['prefix'] ? $this->options['prefix'] . DIRECTORY_SEPARATOR : '') . '*');
foreach ($files as $path) {
if (is_dir($path)) {
$matches = glob($path . DIRECTORY_SEPARATOR . '*.php');
if (is_array($matches)) {
array_map('unlink', $matches);
}
rmdir($path);
} else {
unlink($path);
}
}
return true;
}
/**
* 删除缓存标签
* @access public
* @param array $keys 缓存标识列表
* @return void
*/
public function clearTag(array $keys): void
{
foreach ($keys as $key) {
$this->unlink($key);
}
}
/**
* 判断文件是否存在后,删除
* @access private
* @param string $path
* @return bool
*/
private function unlink(string $path): bool
{
return is_file($path) && unlink($path);
}
}

View File

@@ -1,208 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2019 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
namespace think\cache\driver;
use think\cache\Driver;
/**
* Memcache缓存类
*/
class Memcache extends Driver
{
/**
* 配置参数
* @var array
*/
protected $options = [
'host' => '127.0.0.1',
'port' => 11211,
'expire' => 0,
'timeout' => 0, // 超时时间(单位:毫秒)
'persistent' => true,
'prefix' => '',
'tag_prefix' => 'tag:',
'serialize' => [],
];
/**
* 架构函数
* @access public
* @param array $options 缓存参数
* @throws \BadFunctionCallException
*/
public function __construct(array $options = [])
{
if (!extension_loaded('memcache')) {
throw new \BadFunctionCallException('not support: memcache');
}
if (!empty($options)) {
$this->options = array_merge($this->options, $options);
}
$this->handler = new \Memcache;
// 支持集群
$hosts = (array) $this->options['host'];
$ports = (array) $this->options['port'];
if (empty($ports[0])) {
$ports[0] = 11211;
}
// 建立连接
foreach ($hosts as $i => $host) {
$port = $ports[$i] ?? $ports[0];
$this->options['timeout'] > 0 ?
$this->handler->addServer($host, (int) $port, $this->options['persistent'], 1, $this->options['timeout']) :
$this->handler->addServer($host, (int) $port, $this->options['persistent'], 1);
}
}
/**
* 判断缓存
* @access public
* @param string $name 缓存变量名
* @return bool
*/
public function has($name): bool
{
$key = $this->getCacheKey($name);
return false !== $this->handler->get($key);
}
/**
* 读取缓存
* @access public
* @param string $name 缓存变量名
* @param mixed $default 默认值
* @return mixed
*/
public function get($name, $default = null)
{
$this->readTimes++;
$result = $this->handler->get($this->getCacheKey($name));
return false !== $result ? $this->unserialize($result) : $default;
}
/**
* 写入缓存
* @access public
* @param string $name 缓存变量名
* @param mixed $value 存储数据
* @param int|\DateTime $expire 有效时间(秒)
* @return bool
*/
public function set($name, $value, $expire = null): bool
{
$this->writeTimes++;
if (is_null($expire)) {
$expire = $this->options['expire'];
}
$key = $this->getCacheKey($name);
$expire = $this->getExpireTime($expire);
$value = $this->serialize($value);
if ($this->handler->set($key, $value, 0, $expire)) {
return true;
}
return false;
}
/**
* 自增缓存(针对数值缓存)
* @access public
* @param string $name 缓存变量名
* @param int $step 步长
* @return false|int
*/
public function inc(string $name, int $step = 1)
{
$this->writeTimes++;
$key = $this->getCacheKey($name);
if ($this->handler->get($key)) {
return $this->handler->increment($key, $step);
}
return $this->handler->set($key, $step);
}
/**
* 自减缓存(针对数值缓存)
* @access public
* @param string $name 缓存变量名
* @param int $step 步长
* @return false|int
*/
public function dec(string $name, int $step = 1)
{
$this->writeTimes++;
$key = $this->getCacheKey($name);
$value = $this->handler->get($key) - $step;
$res = $this->handler->set($key, $value);
return !$res ? false : $value;
}
/**
* 删除缓存
* @access public
* @param string $name 缓存变量名
* @param bool|false $ttl
* @return bool
*/
public function delete($name, $ttl = false): bool
{
$this->writeTimes++;
$key = $this->getCacheKey($name);
return false === $ttl ?
$this->handler->delete($key) :
$this->handler->delete($key, $ttl);
}
/**
* 清除缓存
* @access public
* @return bool
*/
public function clear(): bool
{
$this->writeTimes++;
return $this->handler->flush();
}
/**
* 删除缓存标签
* @access public
* @param array $keys 缓存标识列表
* @return void
*/
public function clearTag(array $keys): void
{
foreach ($keys as $key) {
$this->handler->delete($key);
}
}
}

View File

@@ -1,220 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2019 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
namespace think\cache\driver;
use think\cache\Driver;
/**
* Memcached缓存类
*/
class Memcached extends Driver
{
/**
* 配置参数
* @var array
*/
protected $options = [
'host' => '127.0.0.1',
'port' => 11211,
'expire' => 0,
'timeout' => 0, // 超时时间(单位:毫秒)
'prefix' => '',
'username' => '', //账号
'password' => '', //密码
'option' => [],
'tag_prefix' => 'tag:',
'serialize' => [],
];
/**
* 架构函数
* @access public
* @param array $options 缓存参数
*/
public function __construct(array $options = [])
{
if (!extension_loaded('memcached')) {
throw new \BadFunctionCallException('not support: memcached');
}
if (!empty($options)) {
$this->options = array_merge($this->options, $options);
}
$this->handler = new \Memcached;
if (!empty($this->options['option'])) {
$this->handler->setOptions($this->options['option']);
}
// 设置连接超时时间(单位:毫秒)
if ($this->options['timeout'] > 0) {
$this->handler->setOption(\Memcached::OPT_CONNECT_TIMEOUT, $this->options['timeout']);
}
// 支持集群
$hosts = (array) $this->options['host'];
$ports = (array) $this->options['port'];
if (empty($ports[0])) {
$ports[0] = 11211;
}
// 建立连接
$servers = [];
foreach ($hosts as $i => $host) {
$servers[] = [$host, $ports[$i] ?? $ports[0], 1];
}
$this->handler->addServers($servers);
if ('' != $this->options['username']) {
$this->handler->setOption(\Memcached::OPT_BINARY_PROTOCOL, true);
$this->handler->setSaslAuthData($this->options['username'], $this->options['password']);
}
}
/**
* 判断缓存
* @access public
* @param string $name 缓存变量名
* @return bool
*/
public function has($name): bool
{
$key = $this->getCacheKey($name);
return $this->handler->get($key) ? true : false;
}
/**
* 读取缓存
* @access public
* @param string $name 缓存变量名
* @param mixed $default 默认值
* @return mixed
*/
public function get($name, $default = null)
{
$this->readTimes++;
$result = $this->handler->get($this->getCacheKey($name));
return false !== $result ? $this->unserialize($result) : $default;
}
/**
* 写入缓存
* @access public
* @param string $name 缓存变量名
* @param mixed $value 存储数据
* @param integer|\DateTime $expire 有效时间(秒)
* @return bool
*/
public function set($name, $value, $expire = null): bool
{
$this->writeTimes++;
if (is_null($expire)) {
$expire = $this->options['expire'];
}
$key = $this->getCacheKey($name);
$expire = $this->getExpireTime($expire);
$value = $this->serialize($value);
if ($this->handler->set($key, $value, $expire)) {
return true;
}
return false;
}
/**
* 自增缓存(针对数值缓存)
* @access public
* @param string $name 缓存变量名
* @param int $step 步长
* @return false|int
*/
public function inc(string $name, int $step = 1)
{
$this->writeTimes++;
$key = $this->getCacheKey($name);
if ($this->handler->get($key)) {
return $this->handler->increment($key, $step);
}
return $this->handler->set($key, $step);
}
/**
* 自减缓存(针对数值缓存)
* @access public
* @param string $name 缓存变量名
* @param int $step 步长
* @return false|int
*/
public function dec(string $name, int $step = 1)
{
$this->writeTimes++;
$key = $this->getCacheKey($name);
$value = $this->handler->get($key) - $step;
$res = $this->handler->set($key, $value);
return !$res ? false : $value;
}
/**
* 删除缓存
* @access public
* @param string $name 缓存变量名
* @param bool|false $ttl
* @return bool
*/
public function delete($name, $ttl = false): bool
{
$this->writeTimes++;
$key = $this->getCacheKey($name);
return false === $ttl ?
$this->handler->delete($key) :
$this->handler->delete($key, $ttl);
}
/**
* 清除缓存
* @access public
* @return bool
*/
public function clear(): bool
{
$this->writeTimes++;
return $this->handler->flush();
}
/**
* 删除缓存标签
* @access public
* @param array $keys 缓存标识列表
* @return void
*/
public function clearTag(array $keys): void
{
$this->handler->deleteMulti($keys);
}
}

View File

@@ -1,244 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2019 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
namespace think\cache\driver;
use think\cache\Driver;
/**
* Redis缓存驱动适合单机部署、有前端代理实现高可用的场景性能最好
* 有需要在业务层实现读写分离、或者使用RedisCluster的需求请使用Redisd驱动
*
* 要求安装phpredis扩展https://github.com/nicolasff/phpredis
* @author 尘缘 <130775@qq.com>
*/
class Redis extends Driver
{
/**
* 配置参数
* @var array
*/
protected $options = [
'host' => '127.0.0.1',
'port' => 6379,
'password' => '',
'select' => 0,
'timeout' => 0,
'expire' => 0,
'persistent' => false,
'prefix' => '',
'tag_prefix' => 'tag:',
'serialize' => [],
];
/**
* 架构函数
* @access public
* @param array $options 缓存参数
*/
public function __construct(array $options = [])
{
if (!empty($options)) {
$this->options = array_merge($this->options, $options);
}
if (extension_loaded('redis')) {
$this->handler = new \Redis;
if ($this->options['persistent']) {
$this->handler->pconnect($this->options['host'], (int) $this->options['port'], $this->options['timeout'], 'persistent_id_' . $this->options['select']);
} else {
$this->handler->connect($this->options['host'], (int) $this->options['port'], $this->options['timeout']);
}
if ('' != $this->options['password']) {
$this->handler->auth($this->options['password']);
}
} elseif (class_exists('\Predis\Client')) {
$params = [];
foreach ($this->options as $key => $val) {
if (in_array($key, ['aggregate', 'cluster', 'connections', 'exceptions', 'prefix', 'profile', 'replication', 'parameters'])) {
$params[$key] = $val;
unset($this->options[$key]);
}
}
if ('' == $this->options['password']) {
unset($this->options['password']);
}
$this->handler = new \Predis\Client($this->options, $params);
$this->options['prefix'] = '';
} else {
throw new \BadFunctionCallException('not support: redis');
}
if (0 != $this->options['select']) {
$this->handler->select($this->options['select']);
}
}
/**
* 判断缓存
* @access public
* @param string $name 缓存变量名
* @return bool
*/
public function has($name): bool
{
return $this->handler->exists($this->getCacheKey($name));
}
/**
* 读取缓存
* @access public
* @param string $name 缓存变量名
* @param mixed $default 默认值
* @return mixed
*/
public function get($name, $default = null)
{
$this->readTimes++;
$value = $this->handler->get($this->getCacheKey($name));
if (is_null($value) || false === $value) {
return $default;
}
return $this->unserialize($value);
}
/**
* 写入缓存
* @access public
* @param string $name 缓存变量名
* @param mixed $value 存储数据
* @param integer|\DateTime $expire 有效时间(秒)
* @return bool
*/
public function set($name, $value, $expire = null): bool
{
$this->writeTimes++;
if (is_null($expire)) {
$expire = $this->options['expire'];
}
$key = $this->getCacheKey($name);
$expire = $this->getExpireTime($expire);
$value = $this->serialize($value);
if ($expire) {
$this->handler->setex($key, $expire, $value);
} else {
$this->handler->set($key, $value);
}
return true;
}
/**
* 自增缓存(针对数值缓存)
* @access public
* @param string $name 缓存变量名
* @param int $step 步长
* @return false|int
*/
public function inc(string $name, int $step = 1)
{
$this->writeTimes++;
$key = $this->getCacheKey($name);
return $this->handler->incrby($key, $step);
}
/**
* 自减缓存(针对数值缓存)
* @access public
* @param string $name 缓存变量名
* @param int $step 步长
* @return false|int
*/
public function dec(string $name, int $step = 1)
{
$this->writeTimes++;
$key = $this->getCacheKey($name);
return $this->handler->decrby($key, $step);
}
/**
* 删除缓存
* @access public
* @param string $name 缓存变量名
* @return bool
*/
public function delete($name): bool
{
$this->writeTimes++;
$this->handler->del($this->getCacheKey($name));
return true;
}
/**
* 清除缓存
* @access public
* @return bool
*/
public function clear(): bool
{
$this->writeTimes++;
$this->handler->flushDB();
return true;
}
/**
* 删除缓存标签
* @access public
* @param array $keys 缓存标识列表
* @return void
*/
public function clearTag(array $keys): void
{
// 指定标签清除
$this->handler->del($keys);
}
/**
* 追加(数组)缓存数据
* @access public
* @param string $name 缓存标识
* @param mixed $value 数据
* @return void
*/
public function push(string $name, $value): void
{
$this->handler->sAdd($name, $value);
}
/**
* 获取标签包含的缓存标识
* @access public
* @param string $tag 缓存标签
* @return array
*/
public function getTagItems(string $tag): array
{
return $this->handler->sMembers($tag);
}
}

View File

@@ -1,174 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2019 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
namespace think\cache\driver;
use think\cache\Driver;
/**
* Wincache缓存驱动
*/
class Wincache extends Driver
{
/**
* 配置参数
* @var array
*/
protected $options = [
'prefix' => '',
'expire' => 0,
'tag_prefix' => 'tag:',
'serialize' => [],
];
/**
* 架构函数
* @access public
* @param array $options 缓存参数
* @throws \BadFunctionCallException
*/
public function __construct(array $options = [])
{
if (!function_exists('wincache_ucache_info')) {
throw new \BadFunctionCallException('not support: WinCache');
}
if (!empty($options)) {
$this->options = array_merge($this->options, $options);
}
}
/**
* 判断缓存
* @access public
* @param string $name 缓存变量名
* @return bool
*/
public function has($name): bool
{
$this->readTimes++;
$key = $this->getCacheKey($name);
return wincache_ucache_exists($key);
}
/**
* 读取缓存
* @access public
* @param string $name 缓存变量名
* @param mixed $default 默认值
* @return mixed
*/
public function get($name, $default = null)
{
$this->readTimes++;
$key = $this->getCacheKey($name);
return wincache_ucache_exists($key) ? $this->unserialize(wincache_ucache_get($key)) : $default;
}
/**
* 写入缓存
* @access public
* @param string $name 缓存变量名
* @param mixed $value 存储数据
* @param integer|\DateTime $expire 有效时间(秒)
* @return bool
*/
public function set($name, $value, $expire = null): bool
{
$this->writeTimes++;
if (is_null($expire)) {
$expire = $this->options['expire'];
}
$key = $this->getCacheKey($name);
$expire = $this->getExpireTime($expire);
$value = $this->serialize($value);
if (wincache_ucache_set($key, $value, $expire)) {
return true;
}
return false;
}
/**
* 自增缓存(针对数值缓存)
* @access public
* @param string $name 缓存变量名
* @param int $step 步长
* @return false|int
*/
public function inc(string $name, int $step = 1)
{
$this->writeTimes++;
$key = $this->getCacheKey($name);
return wincache_ucache_inc($key, $step);
}
/**
* 自减缓存(针对数值缓存)
* @access public
* @param string $name 缓存变量名
* @param int $step 步长
* @return false|int
*/
public function dec(string $name, int $step = 1)
{
$this->writeTimes++;
$key = $this->getCacheKey($name);
return wincache_ucache_dec($key, $step);
}
/**
* 删除缓存
* @access public
* @param string $name 缓存变量名
* @return bool
*/
public function delete($name): bool
{
$this->writeTimes++;
return wincache_ucache_delete($this->getCacheKey($name));
}
/**
* 清除缓存
* @access public
* @return bool
*/
public function clear(): bool
{
$this->writeTimes++;
return wincache_ucache_clear();
}
/**
* 删除缓存标签
* @access public
* @param array $keys 缓存标识列表
* @return void
*/
public function clearTag(array $keys): void
{
wincache_ucache_delete($keys);
}
}

View File

@@ -1,22 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2019 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
declare (strict_types = 1);
namespace think\exception;
use Psr\Cache\InvalidArgumentException as Psr6CacheInvalidArgumentInterface;
use Psr\SimpleCache\InvalidArgumentException as SimpleCacheInvalidArgumentInterface;
/**
* 非法数据异常
*/
class InvalidArgumentException extends \InvalidArgumentException implements Psr6CacheInvalidArgumentInterface, SimpleCacheInvalidArgumentInterface
{
}

View File

@@ -1,31 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2019 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
declare (strict_types = 1);
namespace think\facade;
use think\Facade;
/**
* @see \think\CacheManager
* @mixin \think\CacheManager
*/
class Cache extends Facade
{
/**
* 获取当前Facade对应类名或者已经绑定的容器对象标识
* @access protected
* @return string
*/
protected static function getFacadeClass()
{
return 'think\CacheManager';
}
}

View File

@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2022 webman
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.

View File

@@ -1,2 +0,0 @@
# think-cache
webman think-cache plugin

View File

@@ -1,13 +0,0 @@
{
"name": "webman/think-cache",
"type": "library",
"license": "MIT",
"require": {
"topthink/think-cache": "^2.0.6"
},
"autoload": {
"psr-4": {
"Webman\\ThinkCache\\": "src"
}
}
}

View File

@@ -1,93 +0,0 @@
<?php
namespace Webman\ThinkCache;
class Install
{
const WEBMAN_PLUGIN = true;
/**
* @var array
*/
protected static $pathRelation = [
'config/thinkcache.php' => 'config/thinkcache.php'
];
/**
* Install
* @return void
*/
public static function install()
{
$config_file = config_path() . '/bootstrap.php';
$config = include $config_file;
if(!in_array(ThinkCache::class, $config ?? [])) {
$config_file_content = file_get_contents($config_file);
$config_file_content = preg_replace('/\];/', " Webman\ThinkCache\ThinkCache::class,\n];", $config_file_content);
file_put_contents($config_file, $config_file_content);
}
/*$thinkcache_file = config_path() . '/thinkcache.php';
if (!is_file($thinkcache_file)) {
copy(__DIR__ . '/config/thinkcache.php', $thinkcache_file);
}*/
static::installByRelation();
}
/**
* Uninstall
* @return void
*/
public static function uninstall()
{
$config_file = config_path() . '/bootstrap.php';
$config = include $config_file;
if(in_array(ThinkCache::class, $config ?? [])) {
$config_file = config_path() . '/bootstrap.php';
$config_file_content = file_get_contents($config_file);
$config_file_content = preg_replace('/ {0,4}Webman\\\\ThinkCache\\\\ThinkCache::class,?\r?\n?/', '', $config_file_content);
file_put_contents($config_file, $config_file_content);
}
self::uninstallByRelation();
}
/**
* installByRelation
* @return void
*/
public static function installByRelation()
{
foreach (static::$pathRelation as $source => $dest) {
if ($pos = strrpos($dest, '/')) {
$parent_dir = base_path().'/'.substr($dest, 0, $pos);
if (!is_dir($parent_dir)) {
mkdir($parent_dir, 0777, true);
}
}
//symlink(__DIR__ . "/$source", base_path()."/$dest");
copy_dir(__DIR__ . "/$source", base_path()."/$dest");
echo "Create $dest
";
}
}
/**
* uninstallByRelation
* @return void
*/
public static function uninstallByRelation()
{
foreach (static::$pathRelation as $source => $dest) {
$path = base_path()."/$dest";
if (!is_dir($path) && !is_file($path)) {
continue;
}
echo "Remove $dest
";
if (is_file($path) || is_link($path)) {
unlink($path);
continue;
}
remove_dir($path);
}
}
}

View File

@@ -1,31 +0,0 @@
<?php
namespace Webman\ThinkCache;
use Webman\Bootstrap;
use Workerman\Timer;
use think\facade\Cache;
use think\Container;
use think\DbManager;
class ThinkCache implements Bootstrap
{
public static function start($worker)
{
$config = config('thinkcache');
if (!$config) {
return;
}
Cache::config($config);
if ($worker && $config['default'] === 'redis') {
Timer::add(55, function () {
Cache::get('ping');
});
}
if (class_exists(DbManager::class)) {
$manager_instance = Container::getInstance()->make(DbManager::class);
$manager_instance->setCache(Cache::store());
}
}
}

View File

@@ -1,22 +0,0 @@
<?php
return [
'default' => 'file',
'stores' => [
'file' => [
'type' => 'File',
// 缓存保存目录
'path' => runtime_path() . '/cache/',
// 缓存前缀
'prefix' => '',
// 缓存有效期 0表示永久缓存
'expire' => 0,
],
'redis' => [
'type' => 'redis',
'host' => '127.0.0.1',
'port' => 6379,
'prefix' => '',
'expire' => 0,
],
],
];