Status response objects are needed mostly to make it possible from the
client perspective to differentiate a status response with the payload
"OK" from a normale bulk reply containing "OK".
The biggest change is for commands returning +OK responses: these were
previously translated to TRUE (bool value), but they are now returned
as instances of Predis\Response\Status. Just to illustrate an example
of the possibilities with this change we will use SET since it is the
most widely used command returning +OK:
$response = $client->set('foo', 'bar');
echo $response; // 'OK'
$response == 'OK'; // TRUE
isset($response->ok); // TRUE
$response == true; // TRUE
$response === true; // FALSE
$response instanceof Predis\Response\ObjectInterface; // TRUE
$response instanceof Predis\Response\Status; // TRUE
For those checking responses returned by commands such as SET or PONG,
the breaking change basically lies in the usage of strict comparison:
doing $response === true will now evaluate to FALSE instead of TRUE.
By default Predis caches common status responses such as OK or QUEUED
to lower the memory usage when using pipelines or transactions.
This optimization is mostly useful since connection parameters can be
instantiated more than one time in a script when using clustering or
replication.
A profile is not needed to create instances of basic initialization
commands such as AUTH (authentication) and SELECT (database selection)
since they do not need prefixing and other stuff.
If needed, developers can still extend the base connection factory to
make it use a server profile and configure the client to use it using
options.
When sending raw commands their arguments are not filtered, responses
are not parsed and key prefixes are not applied. The client also does
not throw any exception on Redis errors regardless of its settings.
The first parameter takes the raw arguments of the command (included
its identifier) as defined by the Redis documentation while the second
optional parameter is always populated by reference to indicate when
Redis actually returned an error response.
$client->raw(['PING']); // "PONG"
$client->raw(['SET','foo','bar']); // "OK"
$client->raw(['GET','foo'], $err); // "bar", $err=FALSE
$client->raw(['LPUSH','foo',1], $err); // "WRONGTYPE...", $err=TRUE
Internally, this method creates instances of Predis\Command\RawCommand
that get passed to the underlying connection instance for execution as
if they were usual commands defined by Predis.
Raw commands work in both cluster and replication scenarios since they
are recognized by their command ID, but key prefixing is not supported
since it is done by the profile instance when instantiating commands.
We now have a base test case class for Predis (namely PredisTestCase)
grouping various commonly used utility methods shared by all of the
tests in the suite, greatly improving reusability.
Commands are verified by checking their IDs and optionally arguments.
Passing a command instance is only a shortcut to set the expected ID
and arguments, commands are never compared for identity but always for
equivalence.
Remove recently added lines as they are not entirely true, the client
currently does not apply any key prefixing for any command not created
by Redis profiles even though it is possible now, contrary to v0.8.
[ci skip]
By raw we mean that input arguments are not filtered and responses are
not parsed, which means arguments must follow the command signature as
defined by Redis and complex responses are left untouched.
When instantiating an instance of `Predis\Command\RawCommand` you must
pass at least the command ID. You can pass further arguments in the
array or you can just set them later with `RawCommand::setArguments()`
but you cannot modify the command ID once instantiated.
$command = new Predis\Command\RawCommand(['SET', 'foo', 'bar']);
$response = $client->executeCommand($command);
While higher level abstractions built upon `Predis\Client` should just
use commands created by the profile in use, inner parts of the library
might use raw commands to provide certain functionalities making sure
that input and output of commands are always consistent, independent
of the profile.
We also changed our wording to indentify this kind of abstraction so
instead of using "scripted commands" (kind of broken English) we now
use "scriptable commands".
It was too broad in concept and not really that useful, so for now we
assume that only our base Predis\Profile\RedisProfile class can handle
command processing and we will decide later if we want to add a couple
of more methods to Predis\Profile\ProfileInterface.
While command classes define how the client should filter arguments or
parse responses, key prefixing depends on the actual command signature
as defined by Redis so it really is something that should be handled
separately as the norm.
Developers can define new handlers or override existing ones, but they
can still define the key prefixing logic inside their command classes
by implementing Predis\Command\PrefixableCommandInterface: the key
prefix processor will just use that by overriding any defined handler.
In this method we can put the logic needed to prepare the connection
right before sending the queued commands to the server (e.g. switching
to the master server when connected in replication mode).
Commands such as MULTI, EXEC, DISCARD, WATCH and UNWATCH disregard the
the "exceptions" client option and always result in an exception being
thrown on error responses even when the client is configured to return
those errors ("exceptions" set to FALSE).