Files
hyperf_rbac_framework_serve…/app/Cache/Redis/BaseScript.php
2025-09-17 17:18:18 +08:00

175 lines
3.9 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Cache\Redis;
use App\Lib\Log\Logger;
use Hyperf\Contract\ConfigInterface;
use Hyperf\Redis\Redis;
use Exception;
use Throwable;
abstract class BaseScript
{
/**
* @var string|null
*/
protected ?string $sha1 = null;
/**
* @var bool
*/
protected bool $debugMode;
/**
* @var Redis
*/
protected Redis $redis;
/**
* @var ConfigInterface
*/
protected ConfigInterface $config;
protected Logger $logger;
/**
* @param Redis $redis
* @param ConfigInterface $config
* @param Logger $logger
*/
public function __construct(
Redis $redis,
ConfigInterface $config,
Logger $logger
)
{
$this->redis = $redis;
$this->debugMode = $config->get('app_debug',false);
$this->logger = $logger;
}
/**
* 获取脚本名称对应lua文件名
* @return string
*/
abstract public function getName(): string;
/**
* @param array $keys
* @param array $args
* @param int|null $numKeys
* @return mixed
*/
protected function run(
array $keys,
array $args,
?int $numKeys = null
): mixed
{
$numKeys = $numKeys ?? count($keys);
try {
$script = $this->getScriptContent();
// $this->logExecution($keys, $args, true);
return $this->execute($script, $keys, $args, $numKeys);
} catch (Exception|Throwable $e) {
$this->logExecution($keys, $args, false, $e);
return false;
}
}
/**
* @return string
* @throws Exception
*/
protected function getScriptContent(): string
{
$path = __DIR__.'/Script/'.$this->getName().'.lua';
// $path = __DIR__.'/Lua/'.$this->getName().'.lua';
if (!file_exists($path)) throw new Exception('lua文件不存在');
$content = file_get_contents($path);
if ($content === false) throw new Exception('lua文件读取失败');
return $content;
}
/**
* @param string $script
* @param array $keys
* @param array $args
* @param int $numKeys
* @return mixed
*/
protected function execute(
string $script,
array $keys,
array $args,
int $numKeys
): mixed
{
if (
!$this->debugMode &&
$this->sha1
)
{
try {
return $this->redis->evalsha(
$this->sha1,
array_merge($keys, $args),
$numKeys
);
} catch (Throwable $e)
{
// SHA1 不存在时回避
$this->sha1 = null;
}
}
$result = $this->redis->eval(
$script,
array_merge($keys, $args),
$numKeys
);
$this->sha1 = sha1($script);
return $result;
}
/**
* @param array $keys
* @param array $args
* @param bool $success
* @param Throwable|null $e
* @return void
*/
protected function logExecution(
array $keys,
array $args,
bool $success,
?Throwable $e = null,
): void
{
$context = [
'script' => $this->getName(),
'keys' => $keys,
'args' => $args,
'success' => $success,
'error' => $e?->getMessage(),
'line' => $e?->getLine(),
'trace' => $e?->getTraceAsString()
];
$logStrategy = match(true) {
!$success => $this->logger->error()->error(...),
$this->debugMode => $this->logger->cache()->debug(...),
default => fn() => null // 不记录
};
if (!$logStrategy) return;
$logStrategy('Redis Lua execution', $context);
}
}