<?php
declare (strict_types = 1);
namespace think\cache\driver;
use BadFunctionCallException;
use OutOfBoundsException;
use Predis\Client;
class Predis extends Redis
{
/** @var Redis */
protected $handler;
/**
* 配置参数
* @var array
*/
protected $options = [
'mode' => 'single',
'replication' => 'sentinel',
'service' => 'master',
'cluster' => 'redis',
'scheme' =>'tcp',
'host' => '127.0.0.1',
'port' => 6379,
'password' => '',
'async' => false,
'select' => 0,
'persistent' => false,
'timeout' => 0,
'expire' => 0,
'prefix' => '',
'tag_prefix' => 'tag:',
'serialize' => [],
];
/**
* @var array
*/
private array $params = ['scheme', 'host', 'port', 'password', 'async', 'persistent', 'timeout'];
/**
* @var array
*/
private array $predisOption = ['service','aggregate', 'cluster', 'connections', 'exceptions', 'prefix', 'profile', 'replication', 'parameters'];
/**
* 架构函数
* @access public
* @param array $options 缓存参数
*/
public function __construct(array $options = [])
{
if (class_exists('\Predis\Client')) {
if (!empty($options)) {
$this->options = array_merge($this->options, $options);
}
[$params,$options] = $this->serializeConfig();
$this->handler = new Client($params,$options);
if (0 != $this->options['select']) {
$this->handler->select((int) $this->options['select']);
}
} else {
throw new BadFunctionCallException('not support: predis');
}
}
private function serializeConfig(): array
{
if(in_array($this->options['mode'],['single','sentinel','cluster']))
{
$params = [];
$option = [];
foreach ($this->options as $key => $val) {
in_array($key,$this->predisOption) && $option[$key] = $val;
in_array($key,$this->params) && $params[$key] = $val;
}
if($this->options['mode'] === 'single') {
return [$params,null];
}
elseif ($this->options['mode'] === 'sentinel') {
$sentinel = explode(',',$params['host']);
$option['parameters'] = $params;
unset($option['cluster'],$option['parameters']['host']);
return [$sentinel,$option];
}
else {
$cluster = explode(',',$params['host']);
$option['cluster'] = $this->options['cluster'];
$option['parameters'] = $params;
unset($option['replication'],$option['service'],$option['parameters']['host']);
return [$cluster,$option];
}
}
else
{
throw new OutOfBoundsException("not support redis mode: {$this->options['mode']}");
}
}
}config配置文件cache.php 'Predis' => [
// 驱动方式
'type' => 'Predis',
// 集群模式
'mode' => env('predis.mode','single'),
//哨兵模式
'replication' => 'sentinel',
//哨兵服务名称
'service' => 'master',
//集群模式
'cluster' => 'redis',
// 连接模式
'scheme' =>'tcp',
// 主机列表
'host' => env('predis.host','host.docker.internal'),
// 默认端口号码
'port' => env('predis.port',6379),
// 密码
'password' => env('predis.password',''),
//是否以非阻塞方式建立到服务器的连接
'async' => env('predis.async ',false),
// 默认数据库0-16
'select' => env('predis.select',0),
// 是否持久化连接
'persistent' => env('predis.persistent',false),
// 连接超时时间
'timeout' => env('predis.timeout',5),
// 缓存有效期 (默认为0 表示永久缓存)
'expire' => env('predis.expire',0),
// 缓存键名前缀(默认为空)
'prefix' => env('predis.prefix',''),
// 获取缓存标签前缀
'tag_prefix' => env('predis.tag_prefix','tag:'),
// 序列化机制 例如 ['serialize', 'unserialize']
'serialize' => [],
] 最佳答案