Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
namespace Illuminate\Redis\Connectors;
4
 
5
use Illuminate\Contracts\Redis\Connector;
6
use Illuminate\Redis\Connections\PhpRedisClusterConnection;
7
use Illuminate\Redis\Connections\PhpRedisConnection;
8
use Illuminate\Support\Arr;
9
use Illuminate\Support\Facades\Redis as RedisFacade;
10
use Illuminate\Support\Str;
11
use LogicException;
12
use Redis;
13
use RedisCluster;
14
 
15
class PhpRedisConnector implements Connector
16
{
17
    /**
18
     * Create a new clustered PhpRedis connection.
19
     *
20
     * @param  array  $config
21
     * @param  array  $options
22
     * @return \Illuminate\Redis\Connections\PhpRedisConnection
23
     */
24
    public function connect(array $config, array $options)
25
    {
26
        $formattedOptions = Arr::pull($config, 'options', []);
27
 
28
        if (isset($config['prefix'])) {
29
            $formattedOptions['prefix'] = $config['prefix'];
30
        }
31
 
32
        $connector = function () use ($config, $options, $formattedOptions) {
33
            return $this->createClient(array_merge(
34
                $config, $options, $formattedOptions
35
            ));
36
        };
37
 
38
        return new PhpRedisConnection($connector(), $connector, $config);
39
    }
40
 
41
    /**
42
     * Create a new clustered PhpRedis connection.
43
     *
44
     * @param  array  $config
45
     * @param  array  $clusterOptions
46
     * @param  array  $options
47
     * @return \Illuminate\Redis\Connections\PhpRedisClusterConnection
48
     */
49
    public function connectToCluster(array $config, array $clusterOptions, array $options)
50
    {
51
        $options = array_merge($options, $clusterOptions, Arr::pull($config, 'options', []));
52
 
53
        return new PhpRedisClusterConnection($this->createRedisClusterInstance(
54
            array_map([$this, 'buildClusterConnectionString'], $config), $options
55
        ));
56
    }
57
 
58
    /**
59
     * Build a single cluster seed string from an array.
60
     *
61
     * @param  array  $server
62
     * @return string
63
     */
64
    protected function buildClusterConnectionString(array $server)
65
    {
66
        return $this->formatHost($server).':'.$server['port'].'?'.Arr::query(Arr::only($server, [
67
            'database', 'password', 'prefix', 'read_timeout',
68
        ]));
69
    }
70
 
71
    /**
72
     * Create the Redis client instance.
73
     *
74
     * @param  array  $config
75
     * @return \Redis
76
     *
77
     * @throws \LogicException
78
     */
79
    protected function createClient(array $config)
80
    {
81
        return tap(new Redis, function ($client) use ($config) {
82
            if ($client instanceof RedisFacade) {
83
                throw new LogicException(
84
                    extension_loaded('redis')
85
                        ? 'Please remove or rename the Redis facade alias in your "app" configuration file in order to avoid collision with the PHP Redis extension.'
86
                        : 'Please make sure the PHP Redis extension is installed and enabled.'
87
                );
88
            }
89
 
90
            $this->establishConnection($client, $config);
91
 
92
            if (! empty($config['password'])) {
93
                if (isset($config['username']) && $config['username'] !== '' && is_string($config['password'])) {
94
                    $client->auth([$config['username'], $config['password']]);
95
                } else {
96
                    $client->auth($config['password']);
97
                }
98
            }
99
 
100
            if (isset($config['database'])) {
101
                $client->select((int) $config['database']);
102
            }
103
 
104
            if (! empty($config['prefix'])) {
105
                $client->setOption(Redis::OPT_PREFIX, $config['prefix']);
106
            }
107
 
108
            if (! empty($config['read_timeout'])) {
109
                $client->setOption(Redis::OPT_READ_TIMEOUT, $config['read_timeout']);
110
            }
111
 
112
            if (! empty($config['scan'])) {
113
                $client->setOption(Redis::OPT_SCAN, $config['scan']);
114
            }
115
 
116
            if (! empty($config['name'])) {
117
                $client->client('SETNAME', $config['name']);
118
            }
119
 
120
            if (array_key_exists('serializer', $config)) {
121
                $client->setOption(Redis::OPT_SERIALIZER, $config['serializer']);
122
            }
123
 
124
            if (array_key_exists('compression', $config)) {
125
                $client->setOption(Redis::OPT_COMPRESSION, $config['compression']);
126
            }
127
 
128
            if (array_key_exists('compression_level', $config)) {
129
                $client->setOption(Redis::OPT_COMPRESSION_LEVEL, $config['compression_level']);
130
            }
131
        });
132
    }
133
 
134
    /**
135
     * Establish a connection with the Redis host.
136
     *
137
     * @param  \Redis  $client
138
     * @param  array  $config
139
     * @return void
140
     */
141
    protected function establishConnection($client, array $config)
142
    {
143
        $persistent = $config['persistent'] ?? false;
144
 
145
        $parameters = [
146
            $this->formatHost($config),
147
            $config['port'],
148
            Arr::get($config, 'timeout', 0.0),
149
            $persistent ? Arr::get($config, 'persistent_id', null) : null,
150
            Arr::get($config, 'retry_interval', 0),
151
        ];
152
 
153
        if (version_compare(phpversion('redis'), '3.1.3', '>=')) {
154
            $parameters[] = Arr::get($config, 'read_timeout', 0.0);
155
        }
156
 
157
        if (version_compare(phpversion('redis'), '5.3.0', '>=') && ! is_null($context = Arr::get($config, 'context'))) {
158
            $parameters[] = $context;
159
        }
160
 
161
        $client->{$persistent ? 'pconnect' : 'connect'}(...$parameters);
162
    }
163
 
164
    /**
165
     * Create a new redis cluster instance.
166
     *
167
     * @param  array  $servers
168
     * @param  array  $options
169
     * @return \RedisCluster
170
     */
171
    protected function createRedisClusterInstance(array $servers, array $options)
172
    {
173
        $parameters = [
174
            null,
175
            array_values($servers),
176
            $options['timeout'] ?? 0,
177
            $options['read_timeout'] ?? 0,
178
            isset($options['persistent']) && $options['persistent'],
179
        ];
180
 
181
        if (version_compare(phpversion('redis'), '4.3.0', '>=')) {
182
            $parameters[] = $options['password'] ?? null;
183
        }
184
 
185
        if (version_compare(phpversion('redis'), '5.3.2', '>=') && ! is_null($context = Arr::get($options, 'context'))) {
186
            $parameters[] = $context;
187
        }
188
 
189
        return tap(new RedisCluster(...$parameters), function ($client) use ($options) {
190
            if (! empty($options['prefix'])) {
191
                $client->setOption(RedisCluster::OPT_PREFIX, $options['prefix']);
192
            }
193
 
194
            if (! empty($options['scan'])) {
195
                $client->setOption(RedisCluster::OPT_SCAN, $options['scan']);
196
            }
197
 
198
            if (! empty($options['failover'])) {
199
                $client->setOption(RedisCluster::OPT_SLAVE_FAILOVER, $options['failover']);
200
            }
201
 
202
            if (! empty($options['name'])) {
203
                $client->client('SETNAME', $options['name']);
204
            }
205
 
206
            if (array_key_exists('serializer', $options)) {
207
                $client->setOption(RedisCluster::OPT_SERIALIZER, $options['serializer']);
208
            }
209
 
210
            if (array_key_exists('compression', $options)) {
211
                $client->setOption(RedisCluster::OPT_COMPRESSION, $options['compression']);
212
            }
213
 
214
            if (array_key_exists('compression_level', $options)) {
215
                $client->setOption(RedisCluster::OPT_COMPRESSION_LEVEL, $options['compression_level']);
216
            }
217
        });
218
    }
219
 
220
    /**
221
     * Format the host using the scheme if available.
222
     *
223
     * @param  array  $options
224
     * @return string
225
     */
226
    protected function formatHost(array $options)
227
    {
228
        if (isset($options['scheme'])) {
229
            return Str::start($options['host'], "{$options['scheme']}://");
230
        }
231
 
232
        return $options['host'];
233
    }
234
}