All Versions
Latest Version
Avg Release Cycle
167 days
Latest Release
502 days ago

Changelog History
Page 3

  • v1.0.0 Changes

    June 01, 2016

    ๐Ÿš€ This is not only a new and major release of Predis, but it is an important milestone because it represents the first stable release in terms of API (both public and internal). Lots of changes have been made to improve the overall design and code quality while optimizing the library as much as possible.

    ๐Ÿš€ You can consult the CHANGELOG for more details about changes and bug fixes introduced in this release.

    IMPORTANT NOTE : we switched to PSR-4 for autoloading but PEAR packaging still uses PSR-0 for obvious reasons, the conversion is performed when generating the package using bin/create-pear. We do not plan to support installation through PEAR indefinitely, but we will stick with it for a few more releases.


    ๐Ÿš€ One of the purposes of this new release was to make use of better names for classes, interfaces and namespaces so we ended up with shorter fully-qualified names and a better organization of namespaces. While these changes can be quite radical in certain cases, the truth is that they will most likely affect only code-bases where developers made use of certain classes to extend the library with custom features. Those simply using Predis as a client will not probably notice any difference. Just to make a few examples (for the rest, see the CHANGELOG):

    • ๐Ÿ”ง The Predis\Option namespace is now Predis\Configuration.
    • The Predis\Command\AbstractCommand class is now Predis\Command\Command.
    • The Predis\Command\ScriptedCommand class is now Predis\Command\ScriptCommand.
    • Aggregate connections (cluster, replication) are in the Predis\Connection\Aggregate namespace.
    • Classes representing status and error responses are in the Predis\Response namespace.

    ๐ŸŽ Obviously it is not only a matter of renaming or moving things around, the overall internal design of Predis has been dramatically improved and now certain aspects of the library (such as clustering) are more solid and more open to extension. Last but not least a lot of work has been done to keep performances in check, resulting in less overhead when initializing client instances and no difference at runtime in raw numbers compared to v0.8.x despite the additional flexibility.

    ๐Ÿ‘Œ Improvements

    @method in docblocks: while this is not strictly a feature, now Predis ships with @method tags for Predis\ClientInterface and Predis\ClientContextInterface (pipelines, transactions) so you can leverage autocompletion and inspection while coding with your favourite IDE. This should be a much welcome addition for many developers since it has been requested many times in the last couple of years.

    Server profiles : the default one is now 3.0 (obviously targeting Redis 3.0.0). It is safe to switch now since the are no breaking changes between Redis 2.8 and 3.0. At the same time, the server profile for Redis 1.2 has been removed since it is relatively ancient stuff.

    ๐Ÿ†• New commands : added SENTINEL to the server profile for Redis 2.6 and PUBSUB to the server profile for Redis 2.8. Please note that you will not find CLUSTER and other commands used by redis-cluster in the server profile for Redis 3.0. Internally they are used as raw commands, they may be added in the future though as soon as Redis 3.0 becomes stable.

    Raw commands : now they can be sent simply by providing an array of arguments (comprising of the command ID) to Predis\Client::executeRaw(). This method skips key prefixing (and more generally, any command processor) and response parsing, so it always returns responses as documented on the Redis website. It is also possible to tell when Redis returns an error thanks to the second optional argument populated by reference with a boolean value:

    $response = $client-\>executeRaw(["SET", "foo", "bar"]); // string(2) "OK"$response = $client-\>executeRaw(["STRLEN", "foo"]); // int(3)// When $iserror is TRUE, $response contains the error string.$response = $client-\>executeRaw(["LPUSH", "foo", "bar"], &$iserror);

    ๐Ÿ”„ Changes for ZRANGE-like commands using WITHSCORES : Predis used to return the member and score pair as an array of [$member, $score] when using the WITHSCORES modifier with ZRANGE, ZREVRANGE, ZRANGEBYSCORE and ZREVRANGEBYSCORE. Now the raw response is parsed to a named array so members and their scores can be accessed as $member => $score.

    $members = $client-\>zrange("key", 0, -1, "withscores");// Predis v0.8 (old): [["member1", "score1"], ...]// Predis v1.0 (new): ["member1" =\> "score1", ...]

    The output of ZSCAN has also been changed accordingly in order to reflect the same output, while Predis\Collection\Iterator\SortedSetKey is not affected by this change. NOTE : the ordering of the original response is still preserved thanks to how PHP internally works with named arrays.

    Redis responses : status responses are now returned as instances of Predis\Response\Status and carry their original payload string. +OK is then no more returned to the client as a boolean TRUE, but since a status response can be transparently casted to string one can do $response == "OK" which is also more akin to how Redis replies to clients. Instances of common status responses such as +OK or +QUEUED are shared internally in order to avoid wasting memory. Another change regards custom response parsers in commands (see Predis\Command\CommandInterface::parseResponse()) which are now applied inside consumer classes such as Predis\Client.

    Client options : the fully reworked Predis\Configuration\Options class now has the ability to lazily initialize values using objects that respond to __invoke() and it works even for custom options defined by the user. This is an example of a complex and modular set of options where standard and user-defined options are mixed together, and the ones regarding cluster are initialized lazily only when needed by the client:

    $client = new Predis\Client($parameters, ['exceptions'=\> true,'connections' =\> ['tcp'=\> 'Predis\Connection\PhpiredisStreamConnection',],'distributor' =\> function () {return new Predis\Cluster\Distributor\KetamaRing(); },'strategy'=\> function ($options) {return new Predis\Cluster\PredisStrategy($options-\>distributor); },'cluster'=\> function ($options) {$strategy = $options-\>strategy;$cluster = new Predis\Connection\Aggregate\PredisCluster($strategy);return $cluster; },'profile'=\> function ($options, $option) {$profile = $options-\>getDefault($option);$profile-\>defineCommand("luascript", "Nrk\Command\LuaScriptCommand");return $profile; },]);

    In addition to the client options already supported by v0.8, the new aggregate option overrides both cluster and replication and can be used to initialize an aggregate connection taking full control over its initialization (the return type must be Predis\Connection\AggregateConnectionInterface).

    Cluster with client-side sharding : Predis now uses the same rules defined by the redis-cluster specification when dealing with empty hash-tags {} in keys, so upgrading Predis might affect the distribution of your already-deployed cluster. If you want to make sure that you will not be affected by this change, you can extend Predis\Cluster\PredisStrategy to override the extractKeyTag($key) method and configure the client to use your strategy like this:

    class OldPredisStrategy extends Predis\Cluster\PredisStrategy{protected function extractKeyTag($key) {if (false !== $start = strpos($key, '{')) {if (false !== $end = strpos($key, '}', $start)) {$key = substr($key, ++$start, $end - $start); } }return $key; }}$client = new Predis\Client($nodes, ["cluster" =\> function () {$strategy = new OldPredisStrategy();$cluster = new Predis\Connection\Aggregate\PredisCluster($strategy);return $cluster; },]);

    This is possible because, starting with v1.0, Predis\Connection\Aggregate\PredisCluster accepts an instance of Predis\Cluster\StrategyInterface as the only argument in its constructor instead of Predis\Cluster\Distributor\DistributorInterface. The distributor, on the other hand, is now wrapped by Predis\Cluster\PredisStrategy.

    Pipeline options : Predis\Client::pipeline() now accepts options to choose which kind of pipeline object should be initialized among the ones supported by Predis:

    • atomic : wraps the pipeline in a MULTI / EXEC transaction (Predis\Pipeline\Atomic).

    - fire-and-forget : does not read back responses (Predis\Pipeline\FireAndForget).

    Transaction options : while Predis\Transaction\MultiExec still supports cas, watch and retry, there are also a couple of changes:

    • exceptions : overrides the value of $options->exceptions provided in client options.

    - on_retry : this option has been removed.

    Key prefixing : while changes in this case are completely transparent to users, the prefixing logic has been moved from command classes to the key prefix processor returned by $options->prefix. Commands are recognized by their IDs and developers can define or override the handlers used to prefix keys based on their arguments. This makes it possible to prefix keys also when using the generic Predis\Command\RawCommand class.

    โฌ‡๏ธ Dropped stuff:

    • Obsolete methods : Predis\Client::multiExec() and Predis\Client::pubSub() have been removed after having been deprecated in v0.8.5. The new names for these methods are respectively Predis\Client::transaction() and Predis\Client::pubSubLoop().
    • Iterable multibulk responses : the commonly used Predis\Connection\StreamConnection does not support them anymore and iterable_multibulk has been removed from the default connection parameters. You can still use them with Predis\Connection\CompositeStreamConnection (it is slower, but makes use of a pluggable protocol system) and the classes implementing multibulk iterators are available in the Predis\Response\Iterator namespace.
    • Pipeline executors : they are no more needed after the changes in Predis\Pipeline\Pipeline.

    What's next?

    ๐Ÿš€ Having finally reached v1.0 is a great milestone considering that Predis has been around for 5 years now, but there is obviously more to come: v1.1 will ship with new features and the most important ones will most likely be support for redis-sentinel with replication and support for slaves in redis-cluster. Minor versions will be released more frequently compared to the past, now that the library is considered stable in terms of design and API.

    ๐Ÿ“š There is also another aspect that should really be addressed: documentation. Predis simply does not have enough documentation covering useful features or the inner parts of the library. I plan to resume the initial efforts started in the documentation branch but frankly I hope to receive also some external contributions.

    ๐Ÿš€ All in all I am happy with this release and even though it took 7 months to ship (way more than what I originally planned, mostly due to some busy months) the result is more than satisfactory in terms of quality. Big thanks to everyone who has shared their feedbacks or contributed with suggestions and code!



  • v0.8.7 Changes

    August 01, 2014

    ๐Ÿš€ This is a maintenance release for the 0.8 series. What follows is an overview of the changes and bug fixes introduced in this release, more details are available in the CHANGELOG.

    ๐Ÿ†• New features

    Redis commands

    • โž• Added the profile alias 3.0 for Redis 3.0, but 2.8 is still the default one.
    • โž• Added COMMAND to the server profile for Redis 2.8. This command is actually available since Redis 2.8.13 so it will return a -ERR when executed against older versions of Redis.

    Redis Cluster

    โšก๏ธ The new default for redis-cluster when the client receives a -MOVED response is to fetch an updated slots map automatically from the node target of the persistent redirection. Thanks to this change you can now feed the client constructor with only a few of the nodes in your cluster without the need to use a more complex configuration, so even if your cluster have - let's say - 10 nodes you can still use only a couple or more connection parameters:

    $client = new Predis\Client( ["tcp://", "tcp://"], ["cluster" =\> "redis"]);

    Internally the client fetches the slots map using the new CLUSTER SLOTS command made available since Redis 3.0.0b7, which means your nodes must be upgraded to the most recent beta release of Redis (but you should do it anyway since it is beta software).


    ๐Ÿ›ฐ Implemented PING in our PUB/SUB loop abstraction for Redis >= 3.0.0b8. You can now ping the connection with an optional payload directly from the loop instance, and receive back a PONG message:

    foreach ($pubSubLoop as $message) {switch ($message-\>kind) {case "subscribe":$pubSubLoop-\>ping("hello!");break;case "pong":echo "Pong message with payload $message-\>payload\n";break; }}

    ๐Ÿ› Bug fixes

    • The patch applied in v0.8.6 to fix #180 introduced a regression affecting read/write timeouts in Predis\Connection\PhpiredisStreamConnection so we had to apply a further fix which, unfortunately, absolutely requires PHP 5.4+ meaning that read/write timeouts will be ignored from now on PHP 5.3.


  • v0.8.6 Changes

    July 15, 2014

    ๐Ÿš€ This is a maintenance release for the 0.8 series with some improvements to existing features. What follows is an overview of the changes and bug fixes introduced in this new release, details are also available in the CHANGELOG.

    ๐Ÿ†• New features

    Redis commands

    • 0๏ธโƒฃ Redis 2.8 is the new default server profile. There are no backwards incompatible changes, Redis 2.8 only added new commands so it is safe to switch.
    • ๐Ÿ†• New commands added to the 2.8 profile: PFADD, PFCOUNT, PFMERGE, ZLEXCOUNT, ZRANGEBYLEX and ZREMRANGEBYLEX.

    ๐Ÿ‘Œ Improvements

    Redis Cluster

    ๐Ÿ‘€ When coupled with Redis >= 3.0.0b1 you can now use key hash tags (e.g. key:{hash:tag}) to force certain keys to be stored on the same node, just like it happens with the good old client-side sharding. See commit ba2ffb6.

    ๐Ÿ› Bug fixes

    • Minor tweaks to make this version of Predis compatible with HHVM >= 2.4.0.
    • ๐Ÿ‘€ Using Redis sentinel does not break the parsing of responses to INFO anymore. See issue #154 and commit f4a950b.
    • ๐Ÿ‘€ INCRBYFLOAT is now handled as expected in cluster and replication configurations. See issue #159 and commit c2ae1c6.
    • Fixed the parsing procedure for the output of CLUSTER NODES when fetching the slots map from a node and redis-cluster has slaves in its configuration. See issue #165 and commit e148dc8. NOTE : the new CLUSTER SLOTS command is the proper way to fetch the slots map now, but we'll stick with the old method for this patch release of v0.8 while v1.0.0 will rely on it by default.
    • ๐Ÿ‘€ Prevent a stack overflow when iterating over large Redis collections using our abstraction for cursor-based iterators. See issue #182 and commit b77da84.
    • ๐Ÿ‘€ Properly discards transactions when the server immediately returns an error response (e.g. -OOM or -ERR on invalid arguments for a command) instead of a +QUEUED response. See issue #187 and commit 74817b5.

    Future development

    Believe me, Predis v1.0.0 is on its way and will be released really soon... this time I mean it for real ;-) That said, v0.8 will still be maintaned for a while with a few more patch releases mainly targeted at improving redis-cluster support as much as possible and fixing issues.

    โž• Additional notes


  • v0.8.5 Changes

    January 16, 2014

    ๐Ÿš€ This is a maintenance release for the 0.8 series with some improvements to existing features. What follows is an overview of the changes and bug fixes introduced in this new release, details are also available in the CHANGELOG.

    ๐Ÿ†• New features

    Redis commands

    • โž• Added a new server profile for Redis 2.8. The default value for the profile client option still targets Redis 2.6 and the dev profile now targets Redis 3.0.
    • ๐Ÿ†• New commands added to the 2.8 profile: SCAN, SSCAN, ZSCAN and HSCAN to the server profile for Redis 2.8.

    Collection iterators

    The new cursor-based iterator commands available starting from Redis 2.8 make it possible to iterate Redis collections without blocking the server but developers still need to implement some logic in their applications to fully leverage them. To ease the usage of such commands we added some abstractions in the Predis\Collection namespace in the form of plain old PHP iterators, making it possible to fully iterate Redis collections in your PHP code with something as simple as foreach.

    Redis do not have a cursor-based iterator for lists but we added an abstraction with Predis\Collection\Iterator\ListKey based on LRANGE that tries to mimic a similar behavior while not being exactly the same thing.

    You can find some examples here.

    Raw commands

    It is possible to execute raw commands using Predis\Command\RawCommand and a variable list of command arguments. The main difference with the usual approach is that input arguments are not filtered and complex responses are not parsed, which also means arguments must follow the exact same signature of the command as defined by Redis. Obviously there is no need to create and register a new class to use them:

    $command = Predis\Command\RawCommand::create('SET', 'foo', 'bar');$response = $client-\>executeCommand($command);

    ๐Ÿ“œ Executing commands in this way can be useful to implement internal features, when the user-specified server profile is not accessible or when you need to make sure that your code will not be affected by different argument filtering or response parsing implementations.

    ๐Ÿš€ This feature will be further improved in the next major release.

    ๐Ÿ‘Œ Improvements

    Redis Cluster

    ๐Ÿš€ Some aspects of our abstraction for Redis Cluster have been dramatically improved or fixed while others (such as silent handling of connection failures) will be addressed in later patch releases.

    • The ASKING command is now correctly sent automatically upon -ASK redirections.
    • โšก๏ธ Updated slots maps can be fetched from nodes thanks to the CLUSTER NODES command. By default this is a manual operation but it can be enabled to get automatically done upon -MOVED redirections.
    • It is possible to specify a common set of connection parameters that are applied to connections created on the fly upon redirections to nodes that are not part of the initial pool.

    ๐Ÿ“œ Query string parsing for connection parameters

    ๐Ÿ“œ URI parsing now relies on parse_str for the query string part which has a slightly smaller overhead when the number of fields in the querystring grows. Furthermore:

    • ๐Ÿ“œ Parsing does not break when value of a field contains one or more =.
    • Repeated fieldnames using [] produce an array of values.
    • Empty or incomplete key=value pairs result in an empty string for key.

    ๐Ÿ—„ Deprecations

    ๐Ÿš€ A couple of methods of Predis\Client are now marked as deprecated and will be removed in the next major release:

    • Predis\Client::multiExec(): superseded by Predis\Client::transaction().
    • Predis\Client::pubSub(): superseded by Predis\Client::pubSubLoop(). This change was needed due to the recently introduced PUBSUB command in Redis 2.8.

    Future development

    Aside from a few more tweaks aimed at improving support for the upcoming Redis Cluster there is not much to add or change in the current v0.8 branch. The library is very stable judging by the history of issues opened during the last months so you can expect a couple of patch releases for v0.8 until Redis 3.0 but nothing more. The good news is that the release of the next major version is imminent and Predis will finally hit v1.0! The transition from v0.8 to v1.0 will bring a lot of breaking changes required to polish the API of the library and its internals, but the actual impact on your code (that is, if you plan to upgrade) may vary depending on your kind of usage: in simple scenarios where Predis is used as a mere client without relying on its extensibility, it is pretty much possible that nothing will change for you.

    ๐Ÿš€ You can already start playing with it by requiring "predis/predis": "dev-master" in composer.json. Predis v1.0.0 is planned to be released on the same day of the first beta of Redis Cluster, 10th February 2014.

    โž• Additional notes


  • v0.8.4 Changes

    July 27, 2013
    • โž• Added DUMP and RESTORE to the server profile for Redis 2.6.

    • Connection exceptions now report basic host details in their messages.

    • ๐Ÿ‘ Allow Predis\Connection\PhpiredisConnection to use a random IP when a host actually has several IPs (ISSUE #116).

    • ๐Ÿ›  FIX: allow HMSET when using a cluster of Redis nodes with client-side sharding or redis-cluster (ISSUE #106).

    • ๐Ÿ›  FIX: set WITHSCORES modifer for ZRANGE, ZREVRANGE, ZRANGEBYSCORE and ZREVRANGEBYSCORE only when the options array passed to these commands has WITHSCORES set to true (ISSUE #107).

    • ๐Ÿ›  FIX: scripted commands falling back from EVALSHA to EVAL resulted in PHP errors when using a prefixed client (ISSUE #109).

    • ๐Ÿ›  FIX: Predis\PubSub\DispatcherLoop now works properly when using key prefixing (ISSUE #114).

  • v0.8.3 Changes

    February 18, 2013

    • Implemented the Predis\Connection\PhpiredisStreamConnection class using the phpiredis extension like Predis\Connection\PhpiredisStreamConnection, but without requiring the socket extension since it relies on PHP's streams.

    • Added support for the TCP_NODELAY flag via the tcp_nodelay parameter for stream-based connections, namely Predis\Connection\StreamConnection and Predis\Connection\PhpiredisStreamConnection (requires PHP >= 5.4.0).

    • โšก๏ธ Updated the aggregated connection class for redis-cluster to work with 16384 hash slots instead of 4096 to reflect the recent change from redis unstable (see this commit).

    • The constructor of Predis\Client now accepts a callable as first argument returning Predis\Connection\ConnectionInterface. Users can create their own self-contained strategies to create and set up the underlying connection.

    • ๐Ÿ‘‰ Users should return 0 from Predis\Command\ScriptedCommand::getKeysCount() instead of FALSE to indicate that all of the arguments of a Lua script must be used to populate ARGV[]. This does not represent a breaking change.

    • ๐Ÿšš The Predis\Helpers class has been deprecated and it will be removed in future releases.

  • v0.8.2 Changes

    February 03, 2013
    • โž• Added Predis\Session\SessionHandler to make it easy to store PHP sessions on Redis using Predis. Please note that this class needs either PHP >= 5.4.0 or a polyfill for PHP's SessionHandlerInterface.

    • โž• Added the ability to get the default value of a client option directly from Predis\Option\ClientOption using the getDefault() method by passing the option name or its instance.

    • ๐Ÿ›  FIX: the standard pipeline executor was not using the response parser methods associated to commands to process raw responses (ISSUE #101).

  • v0.8.1 Changes

    January 19, 2013
    • The connections client option can now accept a callable object returning an instance of Predis\Connection\ConnectionFactoryInterface.

    • Client options accepting callable objects as factories now pass their actual instance to the callable as the second argument.

    • Predis\Command\Processor\KeyPrefixProcessor can now be directly casted to string to obtain the current prefix, useful with string interpolation.

    • โž• Added an optional callable argument to Predis\Cluster\Distribution\HashRing and Predis\Cluster\Distribution\KetamaPureRing constructor that can be used to customize how the distributor should extract the connection hash when initializing the nodes distribution (ISSUE #36).

    • Correctly handle TTL and PTTL returning -2 on non existing keys starting with Redis 2.8.

    • ๐Ÿ›  FIX: a missing use directive in Predis\Transaction\MultiExecContext caused PHP errors when Redis did not return +QUEUED replies to commands when inside a MULTI / EXEC context.

    • ๐Ÿ›  FIX: the parseResponse() method implemented for a scripted command was ignored when retrying to execute a Lua script by falling back to EVAL after a -NOSCRIPT error (ISSUE #94).

    • ๐Ÿ›  FIX: when subclassing Predis\Client the getClientFor() method returns a new instance of the subclass instead of a new instance of Predis\Client.

  • v0.8.0 Changes

    October 23, 2012
    • 0๏ธโƒฃ The default server profile for Redis is now 2.6.

    • Certain connection parameters have been renamed:

      • connection_async is now async_connect
      • connection_timeout is now timeout
      • connection_persistent is now persistent
    • ๐Ÿšš The throw_errors connection parameter has been removed and replaced by the new exceptions client option since exceptions on -ERR replies returned by Redis are not generated by connection classes anymore but instead are thrown by the client class and other abstractions such as pipeline contexts.

    • โž• Added smart support for redis-cluster (Redis v3.0) in addition to the usual cluster implementation that uses client-side sharding.

    • Various namespaces and classes have been renamed to follow rules inspired by the Symfony2 naming conventions.

    • The second argument of the constructor of Predis\Client does not accept strings or instances of Predis\Profile\ServerProfileInterface anymore. To specify a server profile you must explicitly set profile in the array of client options.

    • Predis\Command\ScriptedCommand internally relies on EVALSHA instead of EVAL thus avoiding to send Lua scripts bodies on each request. The client automatically resends the command falling back to EVAL when Redis returns a -NOSCRIPT error. Automatic fallback to EVAL does not work with pipelines, inside a MULTI / EXEC context or with plain EVALSHA commands.

    • ๐Ÿ“œ Complex responses are no more parsed by connection classes as they must be processed by consumer classes using the handler associated to the issued command. This means that executing commands directly on connections only returns simple Redis types, but nothing changes when using Predis\Client or the provided abstractions for pipelines and transactions.

    • ๐Ÿ“œ Iterators for multi-bulk replies now skip the response parsing method of the command that generated the response and are passed directly to user code. Pipeline and transaction objects still consume automatically iterators.

    • Cluster and replication connections now extend a new common interface, Predis\Connection\AggregatedConnectionInterface.

    • Predis\Connection\MasterSlaveReplication now uses an external strategy class to handle the logic for checking readable / writable commands and Lua scripts.

    • โšก๏ธ Command pipelines have been optimized for both speed and code cleanness, but at the cost of bringing a breaking change in the signature of the interface for pipeline executors.

    • โž• Added a new pipeline executor that sends commands wrapped in a MULTI / EXEC context to make the execution atomic: if a pipeline fails at a certain point then the whole pipeline is discarded.

    • The key-hashing mechanism for commands is now handled externally and is no more a competence of each command class. This change is neeeded to support both client-side sharding and Redis cluster.

    • ๐Ÿ‘€ Predis\Options\Option is now abstract, see Predis\Option\AbstractOption.

  • v0.7.3 Changes

    June 01, 2012
    • ๐Ÿ†• New commands available in the Redis v2.6 profile (dev): BITOP, BITCOUNT.

    • When the number of keys Predis\Commands\ScriptedCommand is negative, Predis will count from the end of the arguments list to calculate the actual number of keys that will be interpreted as elements for KEYS by the underlying EVAL command.

    • ๐Ÿ›  FIX: examples\CustomDistributionStrategy.php had a mistyped constructor call and produced a bad distribution due to an error as pointed in ISSUE #63. This bug is limited to the above mentioned example and does not affect the classes implemented in the Predis\Distribution namespace.

    • ๐Ÿ›  FIX: Predis\Commands\ServerEvalSHA::getScriptHash() was calculating the hash while it just needs to return the first argument of the command.

    • ๐Ÿ›  FIX: Predis\Autoloader has been modified to allow cascading autoloaders for the Predis namespace.