Async Redis client implementation, built on top of React PHP.
Redis is an open source, advanced, in-memory key-value database. It offers a set of simple, atomic operations in order to work with its primitive data types. Its lightweight design and fast operation makes it an ideal candidate for modern application stacks. This library provides you a simple API to work with your Redis database from within PHP. It enables you to set and query its data or use its PubSub topics to react to incoming events.
- Async execution of Commands - Send any number commands to Redis in parallel (automatic pipeline) and process their responses as soon as results come in. The Promise-based design provides a sane interface to working with async responses.
- Event-driven core - Register your event handler callbacks to react to incoming events, such as an incoming PubSub message or a MONITOR event.
- Lightweight, SOLID design - Provides a thin abstraction that is just good enough and does not get in your way. Future or custom commands and events require no changes to be supported.
- Good test coverage - Comes with an automated tests suite and is regularly tested against versions as old as Redis v2.6+
Table of Contents
Once installed, you can use the following code to connect to your local Redis server and send some requests:
$loop = React\EventLoop\Factory::create();
$factory = new Factory($loop);
$factory->createClient('localhost:6379')->then(function (Client $client) use ($loop) {
$client->set('greeting', 'Hello world');
$client->append('greeting', '!');
$client->get('greeting')->then(function ($greeting) {
// Hello world!
echo $greeting . PHP_EOL;
});
$client->incr('invocation')->then(function ($n) {
echo 'This is invocation #' . $n . PHP_EOL;
});
// end connection once all pending requests have been resolved
$client->end();
});
$loop->run();
See also the examples.
The Factory
is responsible for creating your Client
instance.
It also registers everything with the main EventLoop
.
$loop = \React\EventLoop\Factory::create();
$factory = new Factory($loop);
If you need custom DNS, proxy or TLS settings, you can explicitly pass a
custom instance of the ConnectorInterface
:
$factory = new Factory($loop, $connector);
The createClient($redisUri = null)
method can be used to create a new Client
.
It helps with establishing a plain TCP/IP connection to Redis
and optionally authenticating (AUTH) and selecting the right database (SELECT).
$factory->createClient('localhost:6379')->then(
function (Client $client) {
// client connected (and authenticated)
},
function (Exception $e) {
// an error occurred while trying to connect (or authenticate) client
}
);
You can omit the complete URI if you want to connect to the default address localhost:6379
:
$factory->createClient();
You can omit the port if you're connecting to the default port 6379:
$factory->createClient('localhost');
You can optionally include a password that will be used to authenticate (AUTH command) the client:
$factory->createClient('auth@localhost');
You can optionally include a path that will be used to select (SELECT command) the right database:
$factory->createClient('localhost/2');
The Client
is responsible for exchanging messages with Redis
and keeps track of pending commands.
All Redis commands are automatically available as public methods like this:
$client->get($key);
$client->set($key, $value);
$client->exists($key);
$client->expire($key, $seconds);
$client->mget($key1, $key2, $key3);
$client->multi();
$client->exec();
$client->publish($channel, $payload);
$client->subscribe($channel);
$client->ping();
$client->select($database);
// many more…
Listing all available commands is out of scope here, please refer to the Redis command reference.
All Redis commands are automatically available as public methods via the magic __call()
method.
Each of these commands supports async operation and either resolves with
its results or rejects with an Exception
.
Please see the following section about promises for more details.
Sending commands is async (non-blocking), so you can actually send multiple commands in parallel. Redis will respond to each command request with a response message, pending commands will be pipelined automatically.
Sending commands uses a Promise-based interface that makes it easy to react to when a command is fulfilled (i.e. either successfully resolved or rejected with an error):
$client->set('hello', 'world');
$client->get('hello')->then(function ($response) {
// response received for GET command
echo 'hello ' . $response;
});
The on($eventName, $eventHandler)
method can be used to register a new event handler.
Incoming events and errors will be forwarded to registered event handler callbacks:
// global events:
$client->on('data', function (MessageInterface $message) {
// process an incoming message (raw message object)
});
$client->on('close', function () {
// the connection to Redis just closed
});
$client->on('error', function (Exception $e) {
// and error has just been detected, the connection will terminate...
});
// pubsub events:
$client->on('message', function ($channel, $payload) {
// pubsub message received on given $channel
});
$client->on('pmessage', function ($pattern, $channel, $payload) {
// pubsub message received matching given $pattern
});
$client->on('subscribe', function ($channel, $total) {
// subscribed to given $channel
});
$client->on('psubscribe', function ($pattern, $total) {
// subscribed to matching given $pattern
});
$client->on('unsubscribe', function ($channel, $total) {
// unsubscribed from given $channel
});
$client->on('punsubscribe', function ($pattern, $total) {
// unsubscribed from matching given $pattern
});
// monitor events:
$client->on('monitor', function (StatusReply $message) {
// somebody executed a command
});
The close()
method can be used to force-close the Redis connection and reject all pending commands.
The end()
method can be used to soft-close the Redis connection once all pending commands are completed.
The recommended way to install this library is through Composer. New to Composer?
This will install the latest supported version:
$ composer require clue/redis-react:^1.0
If you care a lot about backwards compatibility, you may also use this:
$ composer require "clue/redis-react:^1.0 || ^0.5"
See also the CHANGELOG for details about version upgrades.
MIT