Project

General

Profile

1 36485 argiro.kok
# Predis #
2
3
[![Latest Stable Version](https://poser.pugx.org/predis/predis/v/stable.png)](https://packagist.org/packages/predis/predis)
4
[![Total Downloads](https://poser.pugx.org/predis/predis/downloads.png)](https://packagist.org/packages/predis/predis)
5
6
Predis is a flexible and feature-complete [Redis](http://redis.io) client library for PHP >= 5.3.
7
8
By default Predis does not require any additional C extension, but it can be optionally paired with
9
[phpiredis](https://github.com/nrk/phpiredis) to lower the overhead of serializing and parsing the
10
Redis protocol. An asynchronous implementation of the client, albeit experimental, is also available
11
through [Predis\Async](https://github.com/nrk/predis-async).
12
13
Predis can be used with [HHVM](http://www.hhvm.com) >= 2.4.0, but there are no guarantees you will
14
not run into unexpected issues (especially with the JIT compiler enabled via `Eval.Jit = true`) due
15
to HHVM being still under heavy development, thus unstable and not yet 100% compatible with PHP.
16
17
More details about the project can be found in our [frequently asked questions](FAQ.md) section or
18
on the online [wiki](https://github.com/nrk/predis/wiki).
19
20
21
## Main features ##
22
23
- Wide range of Redis versions supported (from __1.2__ to __2.8__ and unstable) using profiles.
24
- Clustering via client-side sharding using consistent hashing or custom distributors.
25
- Smart support for [redis-cluster](http://redis.io/topics/cluster-spec) (Redis >= 3.0).
26
- Support for master-slave replication configurations (write on master, read from slaves).
27
- Transparent key prefixing for all Redis commands.
28
- Command pipelining (works on both single and aggregate connections).
29
- Abstraction for Redis transactions (Redis >= 2.0) supporting CAS operations (Redis >= 2.2).
30
- Abstraction for Lua scripting (Redis >= 2.6) with automatic switching between `EVALSHA` or `EVAL`.
31
- Abstraction for `SCAN`, `SSCAN`, `ZSCAN` and `HSCAN` (Redis >= 2.8) based on PHP iterators.
32
- Connections to Redis are established lazily by the client upon the first command.
33
- Support for both TCP/IP and UNIX domain sockets and persistent connections.
34
- Support for [Webdis](http://webd.is) (both `ext-curl` and `ext-phpiredis` are needed).
35
- Support for custom connection classes for providing different network or protocol backends.
36
- Flexible system for defining and registering custom sets of supported commands or profiles.
37
38
39
## How to use Predis ##
40
41
Predis is available on [Packagist](http://packagist.org/packages/predis/predis) which allows a quick
42
installation using [Composer](http://packagist.org/about-composer). Alternatively, the library can
43
be found on our [own PEAR channel](http://pear.nrk.io) for a more traditional installation via PEAR.
44
Ultimately, archives of each release are [available on GitHub](https://github.com/nrk/predis/tags).
45
46
47
### Loading the library ###
48
49
Predis relies on the autoloading features of PHP to load its files when needed and complies with the
50
[PSR-0 standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md) which makes
51
it compatible with most PHP frameworks. Autoloading is handled automatically when dependencies are
52
managed using Composer, but you can also leverage its own autoloader if you are going to use it in a
53
project or script without any PSR-0 compliant autoloading facility:
54
55
```php
56
// Prepend a base path if Predis is not available in your "include_path".
57
require 'Predis/Autoloader.php';
58
59
Predis\Autoloader::register();
60
```
61
62
It is possible to easily create a [phar](http://www.php.net/manual/en/intro.phar.php) archive from
63
the repository just by launching `bin/create-phar`. The generated phar contains a stub defining an
64
autoloader function for Predis, so you just need to require the phar to start using the library.
65
Alternatively, it is also possible to generate one single PHP file that holds every class like older
66
versions of Predis by launching `bin/create-single-file`, but this practice __is not__ encouraged.
67
68
69
### Connecting to Redis ###
70
71
When not specifying any connection parameter to create a new client, Predis assumes `127.0.0.1` and
72
`6379` as the default host and port and uses a connection timeout of 5 seconds:
73
74
```php
75
$client = new Predis\Client();
76
$client->set('foo', 'bar');
77
$value = $client->get('foo');
78
```
79
80
Connection parameters can be supplied either in the form of URI strings or named arrays. While the
81
latter is the preferred way to supply parameters, URI strings can be useful for quick configurations
82
or when parameters are read from a non-structured source:
83
84
```php
85
// Named array of connection parameters:
86
$client = new Predis\Client([
87
    'scheme' => 'tcp',
88
    'host'   => '10.0.0.1',
89
    'port'   => 6379,
90
]);
91
92
// Same set of parameters, but using an URI string:
93
$client = new Predis\Client('tcp://10.0.0.1:6379');
94
```
95
96
When an array of connections parameters is provided, Predis automatically works in clustering mode
97
using client-side sharding. Both named arrays and URI strings can be mixed for providing each node
98
configuration:
99
100
```php
101
$client = new Predis\Client([
102
    'tcp://10.0.0.1?alias=first-node',
103
    ['host' => '10.0.0.2', 'alias' => 'second-node'],
104
]);
105
```
106
107
The actual list of supported connection parameters can vary depending on each connection backend so
108
it is recommended to refer to their specific documentation for details.
109
110
111
### Client configuration ###
112
113
Various aspects of the client can be easily configured by passing options to the second argument of
114
`Predis\Client::__construct()`. Options are managed using a mini DI-alike container and their values
115
are usually lazily initialized only when needed. Predis by default supports the following options:
116
117
  - `profile`: which profile to use in order to match a specific version of Redis.
118
  - `prefix`: a prefix string that is automatically applied to keys found in commands.
119
  - `exceptions`: whether the client should throw or return responses upon Redis errors.
120
  - `connections`: connection backends or a connection factory to be used by the client.
121
  - `cluster`: which backend to use for clustering (predis, redis or custom configuration).
122
  - `replication`: which backend to use for replication (predis or custom configuration).
123
124
Users can provide custom option values, they are stored in the options container and can be accessed
125
later through the library.
126
127
128
### Aggregate connections ###
129
130
Predis is able to aggregate multiple connections which is the base for clustering and replication.
131
By default the client implements clustering using either client-side sharding (default) or a Redis
132
backed solution using [redis-cluster](http://redis.io/topics/cluster-tutorial). As for replication,
133
Predis can handle single-master and multiple-slaves setups by executing read operations on slaves
134
and switching to the master for write operations. The replication behaviour is fully configurable.
135
136
137
### Command pipelines ###
138
139
Pipelining can help with performances when many commands need to be sent to a server by reducing the
140
latency introduced by network round-trip timings. Pipelining also works with aggregate connections.
141
The client can execute the pipeline inside a callable block or return a pipeline instance with the
142
ability to chain commands thanks to its fluent interface:
143
144
```php
145
// Executes a pipeline inside a given callable block:
146
$responses = $client->pipeline(function ($pipe) {
147
    for ($i = 0; $i < 1000; $i++) {
148
        $pipe->set("key:$i", str_pad($i, 4, '0', 0));
149
        $pipe->get("key:$i");
150
    }
151
});
152
153
// Returns a pipeline instance with fluent interface:
154
$responses = $client->pipeline()->set('foo', 'bar')->get('foo')->execute();
155
```
156
157
158
### Transactions ###
159
160
The client provides an abstraction for Redis transactions based on `MULTI` and `EXEC` with a similar
161
interface to command pipelines:
162
163
```php
164
// Executes a transaction inside a given callable block:
165
$responses = $client->transaction(function ($tx) {
166
    $tx->set('foo', 'bar');
167
    $tx->get('foo');
168
});
169
170
// Returns a transaction instance with fluent interface:
171
$responses = $client->transaction()->set('foo', 'bar')->get('foo')->execute();
172
```
173
174
This abstraction can perform check-and-set operations thanks to `WATCH` and `UNWATCH` and provides
175
automatic retries of transactions aborted by Redis when `WATCH`ed keys are touched. For an example
176
of a transaction using CAS you can see [the following example](examples/TransactionWithCAS.php).
177
178
__NOTE__: the method `transaction()` is available since `v0.8.5`, older versions used `multiExec()`
179
for the same purpose but it has been deprecated and will be removed in the next major release.
180
181
182
### Customizable connection backends ###
183
184
Predis can use different connection backends to connect to Redis. Two of them leverage a third party
185
extension such as [phpiredis](https://github.com/nrk/phpiredis) resulting in major performance gains
186
especially when dealing with big multibulk responses. While one is based on PHP streams, the other
187
is based on socket resources provided by `ext-socket`. Both support TCP/IP or UNIX domain sockets:
188
189
```php
190
$client = new Predis\Client('tcp://127.0.0.1', [
191
    'connections' => [
192
        'tcp'  => 'Predis\Connection\PhpiredisStreamConnection', // PHP streams
193
        'unix' => 'Predis\Connection\PhpiredisConnection',       // ext-socket
194
    ],
195
]);
196
```
197
198
Developers can create their own connection classes to add support for new network backends, extend
199
existing ones or provide completely different implementations. Connection classes must implement
200
`Predis\Connection\SingleConnectionInterface` or extend `Predis\Connection\AbstractConnection`:
201
202
```php
203
class MyConnectionClass implements Predis\Connection\SingleConnectionInterface
204
{
205
    // Implementation goes here...
206
}
207
208
// Use MyConnectionClass to handle connections for the `tcp` scheme:
209
$client = new Predis\Client('tcp://127.0.0.1', [
210
    'connections' => ['tcp' => 'MyConnectionClass'],
211
]);
212
```
213
214
For a more in-depth insight on how to create new connection backends you can refer to the actual
215
implementation of the standard connection classes available in the `Predis\Connection` namespace.
216
217
218
### Adding support for new commands ###
219
220
While we try to update Predis to stay up to date with all the commands available in Redis, you might
221
prefer to stick with an older version of the library or provide a different way to filter arguments
222
or parse responses for specific commands. To achieve that, Predis provides the ability to implement
223
new command classes to define or override commands in the server profiles used by the client:
224
225
```php
226
// Define a new command by extending Predis\Command\AbstractCommand:
227
class BrandNewRedisCommand extends Predis\Command\AbstractCommand
228
{
229
    public function getId()
230
    {
231
        return 'NEWCMD';
232
    }
233
}
234
235
// Inject your command in the current profile:
236
$client = new Predis\Client();
237
$client->getProfile()->defineCommand('newcmd', 'BrandNewRedisCommand');
238
239
$response = $client->newcmd();
240
```
241
242
243
### Scriptable commands ###
244
245
A scriptable command is just an abstraction for [Lua scripting](http://redis.io/commands/eval) that
246
aims to simplify the usage of scripting with Redis >= 2.6. Scriptable commands can be registered in
247
the server profile used by the client and are accessible as if they were plain Redis commands, but
248
they define a Lua script that gets transmitted to Redis for remote execution. Internally, scriptable
249
commands use by default [EVALSHA](http://redis.io/commands/evalsha) and identify a Lua script by its
250
SHA1 hash to save bandwidth but [EVAL](http://redis.io/commands/eval) is automatically preferred as
251
a fall back when needed:
252
253
```php
254
// Define a new scriptable command by extending Predis\Command\ScriptedCommand:
255
class ListPushRandomValue extends Predis\Command\ScriptedCommand
256
{
257
    public function getKeysCount()
258
    {
259
        return 1;
260
    }
261
262
    public function getScript()
263
    {
264
        return <<<LUA
265
math.randomseed(ARGV[1])
266
local rnd = tostring(math.random())
267
redis.call('lpush', KEYS[1], rnd)
268
return rnd
269
LUA;
270
    }
271
}
272
273
// Inject your scriptable command in the current profile:
274
$client = new Predis\Client();
275
$client->getProfile()->defineCommand('lpushrand', 'ListPushRandomValue');
276
277
$response = $client->lpushrand('random_values', $seed = mt_rand());
278
```
279
280
281
## Development ##
282
283
284
### Reporting bugs and contributing code ###
285
286
Contributions to Predis are highly appreciated either in the form of pull requests for new features,
287
bug fixes, or just bug reports. We only ask you to adhere to a [basic set of rules](CONTRIBUTING.md)
288
before submitting your changes or filing bugs on the issue tracker to make it easier for everyone to
289
stay consistent while working on the project.
290
291
292
### Test suite ###
293
294
__ATTENTION__: Do not ever run the test suite shipped with Predis against instances of Redis running
295
in production environments or containing data you are interested in!
296
297
Predis has a comprehensive test suite covering every aspect of the library. This test suite performs
298
integration tests against a running instance of Redis (>= 2.4.0 is required) to verify the correct
299
behaviour of the implementation of each command and automatically skips commands not defined in the
300
specified Redis profile. If you do not have Redis up and running, integration tests can be disabled.
301
By default the test suite is configured to execute integration tests using the profile for Redis 2.8
302
(which is the current stable version of Redis) but can optionally target a Redis instance built from
303
the `unstable` branch by modifying `phpunit.xml` and setting `REDIS_SERVER_VERSION` to `dev` so that
304
the development server profile will be used. You can refer to [the tests README](tests/README.md)
305
for more detailed information about testing Predis.
306
307
Predis uses Travis CI for continuous integration and the history for past and current builds can be
308
found [on its project page](http://travis-ci.org/nrk/predis).
309
310
311
## Other ##
312
313
314
### Project related links ###
315
316
- [Source code](https://github.com/nrk/predis)
317
- [Wiki](https://wiki.github.com/nrk/predis)
318
- [Issue tracker](https://github.com/nrk/predis/issues)
319
- [PEAR channel](http://pear.nrk.io)
320
321
322
### Author ###
323
324
- [Daniele Alessandri](mailto:suppakilla@gmail.com) ([twitter](http://twitter.com/JoL1hAHN))
325
326
327
### License ###
328
329
The code for Predis is distributed under the terms of the MIT license (see [LICENSE](LICENSE)).