TP6 Predis驱动扩展(单机,集群,哨兵)

浏览:883 发布日期:2021/04/20 分类:ThinkPHP6专区
文件位置/extend/think/cache/driver/Predis.php<?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'   => [],
        ]
最佳答案
评论( 相关
后面还有条评论,点击查看>>