mirror of
https://github.com/predis/predis.git
synced 2026-08-19 14:02:01 +00:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| deee2b6d60 | |||
| bb8cce7bcf | |||
| dc14604f3e | |||
| b000013f22 | |||
| d6da14daa8 | |||
| acb2460f4c | |||
| 213f00042f | |||
| ab0c46332c | |||
| ed19ec3483 | |||
| 90496e76b5 | |||
| 4231c35e09 | |||
| a2fb02d738 | |||
| ca1f398f7c | |||
| 5e07be785a | |||
| b3cd02e2ba |
@@ -11,3 +11,5 @@
|
||||
/.travis.yml export-ignore
|
||||
/phpunit.xml.dist export-ignore
|
||||
/phpunit.xml.travisci export-ignore
|
||||
/CHANGELOG.md export-ignore
|
||||
/CONTRIBUTING.md export-ignore
|
||||
|
||||
+2
-7
@@ -2,10 +2,8 @@ language: php
|
||||
|
||||
branches:
|
||||
except:
|
||||
- v0.5
|
||||
- v0.6
|
||||
- v0.6-PHP_5.2
|
||||
- documentation
|
||||
- main
|
||||
- v2.0
|
||||
|
||||
before_install:
|
||||
- docker run -d --rm -p 127.0.0.1:6379:6379 redis:3
|
||||
@@ -36,6 +34,3 @@ matrix:
|
||||
- php: 7.3
|
||||
- php: 7.4
|
||||
- php: 8.0
|
||||
- php: nightly
|
||||
allow_failures:
|
||||
- php: nightly
|
||||
|
||||
+10
-2
@@ -1,13 +1,21 @@
|
||||
v1.1.10 (2022-01-05)
|
||||
================================================================================
|
||||
|
||||
- __FIX__: Avoid PHP 8.1 deprecation notices in `Session/Handler`
|
||||
- __FIX__: Fixed "Cannot use object of type Predis\Response\Error as array"
|
||||
error in `Connection/Aggregate/SentinelReplication`
|
||||
|
||||
|
||||
v1.1.9 (2021-10-05)
|
||||
================================================================================
|
||||
|
||||
- Fixed PHP 8.1 compatibility in `StreamConnection`
|
||||
- __FIX__: Fixed PHP 8.1 compatibility in `StreamConnection`
|
||||
|
||||
|
||||
v1.1.8 (2021-09-29)
|
||||
================================================================================
|
||||
|
||||
- Ensure compatibility with PHP 8.1.
|
||||
- __FIX__: Ensure compatibility with PHP 8.1.
|
||||
|
||||
|
||||
v1.1.7 (2021-04-04)
|
||||
|
||||
+2
-2
@@ -10,8 +10,8 @@ name = "Predis"
|
||||
desc = "Flexible and feature-complete Redis client for PHP and HHVM"
|
||||
homepage = "http://github.com/nrk/predis"
|
||||
license = "MIT"
|
||||
version = "1.1.9"
|
||||
stability = "stable"
|
||||
version = "1.1.11"
|
||||
stability = "devel"
|
||||
channel = "pear.nrk.io"
|
||||
|
||||
author = "Daniele Alessandri \"nrk\" <suppakilla@gmail.com>"
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ use Predis\Transaction\MultiExec as MultiExecTransaction;
|
||||
*/
|
||||
class Client implements ClientInterface, \IteratorAggregate
|
||||
{
|
||||
const VERSION = '1.1.9';
|
||||
const VERSION = '1.1.11-dev';
|
||||
|
||||
protected $connection;
|
||||
protected $options;
|
||||
|
||||
@@ -138,6 +138,7 @@ abstract class CursorBasedIterator implements \Iterator
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return void
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function rewind()
|
||||
@@ -148,6 +149,7 @@ abstract class CursorBasedIterator implements \Iterator
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return mixed
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function current()
|
||||
@@ -157,6 +159,7 @@ abstract class CursorBasedIterator implements \Iterator
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return int
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function key()
|
||||
@@ -166,6 +169,7 @@ abstract class CursorBasedIterator implements \Iterator
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return void
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function next()
|
||||
@@ -187,6 +191,7 @@ abstract class CursorBasedIterator implements \Iterator
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return bool
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function valid()
|
||||
|
||||
@@ -127,6 +127,7 @@ class ListKey implements \Iterator
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return void
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function rewind()
|
||||
@@ -137,6 +138,7 @@ class ListKey implements \Iterator
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return mixed
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function current()
|
||||
@@ -146,6 +148,7 @@ class ListKey implements \Iterator
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return int
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function key()
|
||||
@@ -155,6 +158,7 @@ class ListKey implements \Iterator
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return void
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function next()
|
||||
@@ -172,6 +176,7 @@ class ListKey implements \Iterator
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return bool
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function valid()
|
||||
|
||||
@@ -197,7 +197,13 @@ class KeyPrefixProcessor implements ProcessorInterface
|
||||
if ($command instanceof PrefixableCommandInterface) {
|
||||
$command->prefixKeys($this->prefix);
|
||||
} elseif (isset($this->commands[$commandID = strtoupper($command->getId())])) {
|
||||
call_user_func($this->commands[$commandID], $command, $this->prefix);
|
||||
$callable = $this->commands[$commandID];
|
||||
|
||||
if (is_string($callable) && 0 === strpos($callable, 'static::')) {
|
||||
$callable = substr_replace($callable, get_class($this), 0, 6);
|
||||
}
|
||||
|
||||
call_user_func($callable, $command, $this->prefix);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -99,6 +99,7 @@ class ProcessorChain implements \ArrayAccess, ProcessorInterface
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return ProcessorInterface|null
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetGet($index)
|
||||
@@ -108,6 +109,7 @@ class ProcessorChain implements \ArrayAccess, ProcessorInterface
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return void
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetSet($index, $processor)
|
||||
@@ -124,6 +126,7 @@ class ProcessorChain implements \ArrayAccess, ProcessorInterface
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return void
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetUnset($index)
|
||||
|
||||
@@ -20,6 +20,7 @@ use Predis\Connection\NodeConnectionInterface;
|
||||
use Predis\Connection\Parameters;
|
||||
use Predis\Replication\ReplicationStrategy;
|
||||
use Predis\Replication\RoleException;
|
||||
use Predis\Response\Error;
|
||||
use Predis\Response\ErrorInterface as ErrorResponseInterface;
|
||||
use Predis\Response\ServerException;
|
||||
|
||||
@@ -523,13 +524,17 @@ class SentinelReplication implements ReplicationInterface
|
||||
* @param NodeConnectionInterface $connection Connection to a redis server.
|
||||
* @param string $role Expected role of the server ("master", "slave" or "sentinel").
|
||||
*
|
||||
* @throws RoleException
|
||||
* @throws RoleException|ConnectionException
|
||||
*/
|
||||
protected function assertConnectionRole(NodeConnectionInterface $connection, $role)
|
||||
{
|
||||
$role = strtolower($role);
|
||||
$actualRole = $connection->executeCommand(RawCommand::create('ROLE'));
|
||||
|
||||
if ($actualRole instanceof Error) {
|
||||
throw new ConnectionException($connection, $actualRole->getMessage());
|
||||
}
|
||||
|
||||
if ($role !== $actualRole[0]) {
|
||||
throw new RoleException($connection, "Expected $role but got $actualRole[0] [$connection]");
|
||||
}
|
||||
|
||||
@@ -123,8 +123,9 @@ class PhpiredisStreamConnection extends StreamConnection
|
||||
{
|
||||
$socket = null;
|
||||
$timeout = (isset($parameters->timeout) ? (float) $parameters->timeout : 5.0);
|
||||
$context = stream_context_create();
|
||||
|
||||
$resource = @stream_socket_client($address, $errno, $errstr, $timeout, $flags);
|
||||
$resource = @stream_socket_client($address, $errno, $errstr, $timeout, $flags, $context);
|
||||
|
||||
if (!$resource) {
|
||||
$this->onConnectionError(trim($errstr), $errno);
|
||||
|
||||
@@ -123,8 +123,9 @@ class StreamConnection extends AbstractConnection
|
||||
protected function createStreamSocket(ParametersInterface $parameters, $address, $flags)
|
||||
{
|
||||
$timeout = (isset($parameters->timeout) ? (float) $parameters->timeout : 5.0);
|
||||
$context = stream_context_create();
|
||||
|
||||
if (!$resource = @stream_socket_client($address, $errno, $errstr, $timeout, $flags)) {
|
||||
if (!$resource = @stream_socket_client($address, $errno, $errstr, $timeout, $flags, $context)) {
|
||||
$this->onConnectionError(trim($errstr), $errno);
|
||||
}
|
||||
|
||||
@@ -288,7 +289,7 @@ class StreamConnection extends AbstractConnection
|
||||
$socket = $this->getResource();
|
||||
|
||||
while (($length = strlen($buffer)) > 0) {
|
||||
$written = @fwrite($socket, $buffer);
|
||||
$written = is_resource($socket) ? @fwrite($socket, $buffer) : false;
|
||||
|
||||
if ($length === $written) {
|
||||
return;
|
||||
@@ -332,7 +333,7 @@ class StreamConnection extends AbstractConnection
|
||||
$bytesLeft = ($size += 2);
|
||||
|
||||
do {
|
||||
$chunk = fread($socket, min($bytesLeft, 4096));
|
||||
$chunk = is_resource($socket) ? fread($socket, min($bytesLeft, 4096)) : false;
|
||||
|
||||
if ($chunk === false || $chunk === '') {
|
||||
$this->onConnectionError('Error while reading bytes from the server.');
|
||||
|
||||
@@ -24,7 +24,7 @@ class Consumer implements \Iterator
|
||||
{
|
||||
private $client;
|
||||
private $valid;
|
||||
private $position;
|
||||
private $position = 0;
|
||||
|
||||
/**
|
||||
* @param ClientInterface $client Client instance used by the consumer.
|
||||
@@ -90,6 +90,7 @@ class Consumer implements \Iterator
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return void
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function rewind()
|
||||
@@ -110,6 +111,7 @@ class Consumer implements \Iterator
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return int
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function key()
|
||||
@@ -119,6 +121,7 @@ class Consumer implements \Iterator
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return void
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function next()
|
||||
|
||||
@@ -225,6 +225,19 @@ class Pipeline implements ClientContextInterface
|
||||
return $this->responses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the buffer holding all of the commands and responses.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
$this->responses = array();
|
||||
$this->pipeline = new \SplQueue();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the pipeline should throw exceptions on server errors.
|
||||
*
|
||||
|
||||
@@ -30,7 +30,7 @@ abstract class AbstractConsumer implements \Iterator
|
||||
const STATUS_SUBSCRIBED = 2; // 0b0010
|
||||
const STATUS_PSUBSCRIBED = 4; // 0b0100
|
||||
|
||||
private $position = null;
|
||||
private $position = 0;
|
||||
private $statusFlags = self::STATUS_VALID;
|
||||
|
||||
/**
|
||||
@@ -150,6 +150,7 @@ abstract class AbstractConsumer implements \Iterator
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return void
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function rewind()
|
||||
@@ -161,7 +162,7 @@ abstract class AbstractConsumer implements \Iterator
|
||||
* Returns the last message payload retrieved from the server and generated
|
||||
* by one of the active subscriptions.
|
||||
*
|
||||
* @return array
|
||||
* @return \stdClass
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function current()
|
||||
@@ -171,6 +172,7 @@ abstract class AbstractConsumer implements \Iterator
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return int
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function key()
|
||||
@@ -218,7 +220,7 @@ abstract class AbstractConsumer implements \Iterator
|
||||
* Waits for a new message from the server generated by one of the active
|
||||
* subscriptions and returns it when available.
|
||||
*
|
||||
* @return array
|
||||
* @return \stdClass
|
||||
*/
|
||||
abstract protected function getValue();
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@ use Predis\ClientInterface;
|
||||
use Predis\Command\Command;
|
||||
use Predis\Connection\AggregateConnectionInterface;
|
||||
use Predis\NotSupportedException;
|
||||
use Predis\Response\ServerException;
|
||||
use Predis\Response\Error;
|
||||
|
||||
/**
|
||||
* PUB/SUB consumer abstraction.
|
||||
@@ -116,6 +118,10 @@ class Consumer extends AbstractConsumer
|
||||
{
|
||||
$response = $this->client->getConnection()->read();
|
||||
|
||||
if ($response instanceof Error) {
|
||||
throw new ServerException($response->getMessage());
|
||||
}
|
||||
|
||||
switch ($response[0]) {
|
||||
case self::SUBSCRIBE:
|
||||
case self::UNSUBSCRIBE:
|
||||
|
||||
@@ -33,6 +33,7 @@ abstract class MultiBulkIterator implements \Iterator, \Countable, ResponseInter
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return void
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function rewind()
|
||||
@@ -42,6 +43,7 @@ abstract class MultiBulkIterator implements \Iterator, \Countable, ResponseInter
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return mixed
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function current()
|
||||
@@ -51,6 +53,7 @@ abstract class MultiBulkIterator implements \Iterator, \Countable, ResponseInter
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return int
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function key()
|
||||
@@ -60,6 +63,7 @@ abstract class MultiBulkIterator implements \Iterator, \Countable, ResponseInter
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return void
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function next()
|
||||
@@ -71,6 +75,7 @@ abstract class MultiBulkIterator implements \Iterator, \Countable, ResponseInter
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return bool
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function valid()
|
||||
|
||||
@@ -60,6 +60,7 @@ class MultiBulkTuple extends MultiBulk implements \OuterIterator
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return \Iterator
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function getInnerIterator()
|
||||
|
||||
@@ -64,7 +64,9 @@ class Handler implements \SessionHandlerInterface
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return bool
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function open($save_path, $session_id)
|
||||
{
|
||||
// NOOP
|
||||
@@ -73,7 +75,9 @@ class Handler implements \SessionHandlerInterface
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return bool
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function close()
|
||||
{
|
||||
// NOOP
|
||||
@@ -82,7 +86,9 @@ class Handler implements \SessionHandlerInterface
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return int|bool
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function gc($maxlifetime)
|
||||
{
|
||||
// NOOP
|
||||
@@ -91,7 +97,9 @@ class Handler implements \SessionHandlerInterface
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return string
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function read($session_id)
|
||||
{
|
||||
if ($data = $this->client->get($session_id)) {
|
||||
@@ -102,7 +110,9 @@ class Handler implements \SessionHandlerInterface
|
||||
}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return bool
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function write($session_id, $session_data)
|
||||
{
|
||||
$this->client->setex($session_id, $this->ttl, $session_data);
|
||||
@@ -112,7 +122,9 @@ class Handler implements \SessionHandlerInterface
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return bool
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function destroy($session_id)
|
||||
{
|
||||
$this->client->del($session_id);
|
||||
|
||||
@@ -234,6 +234,59 @@ class PipelineTest extends PredisTestCase
|
||||
$this->assertSame(array('one', 'two', 'three', 'four'), $pipeline->execute());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group disconnected
|
||||
*/
|
||||
public function testClearBuffer()
|
||||
{
|
||||
$connection = $this->getMock('Predis\Connection\NodeConnectionInterface');
|
||||
$connection->expects($this->never())
|
||||
->method('writeRequest');
|
||||
$connection->expects($this->never())
|
||||
->method('readResponse')
|
||||
->will($this->returnCallback($this->getReadCallback()));
|
||||
|
||||
$pipeline = new Pipeline(new Client($connection));
|
||||
|
||||
$pipeline->echo('one');
|
||||
$pipeline->echo('two');
|
||||
|
||||
$pipeline->clear();
|
||||
|
||||
$this->assertSame(array(), $pipeline->execute());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group disconnected
|
||||
*/
|
||||
public function testClearResponses()
|
||||
{
|
||||
$connection = $this->getMock('Predis\Connection\NodeConnectionInterface');
|
||||
$connection->expects($this->exactly(4))
|
||||
->method('writeRequest');
|
||||
$connection->expects($this->exactly(4))
|
||||
->method('readResponse')
|
||||
->will($this->returnCallback($this->getReadCallback()));
|
||||
|
||||
$pipeline = new Pipeline(new Client($connection));
|
||||
|
||||
$pipeline->echo('one');
|
||||
$pipeline->echo('two');
|
||||
|
||||
$this->assertSame(array('one', 'two'), $pipeline->execute());
|
||||
|
||||
$pipeline->clear();
|
||||
|
||||
$pipeline->echo('three');
|
||||
$pipeline->echo('four');
|
||||
|
||||
$this->assertSame(array('three', 'four'), $pipeline->execute());
|
||||
|
||||
$pipeline->clear();
|
||||
|
||||
$this->assertSame(array(), $pipeline->execute());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group disconnected
|
||||
*/
|
||||
|
||||
@@ -426,4 +426,32 @@ class ConsumerTest extends PredisTestCase
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @group connected
|
||||
* @expectedException \Predis\Response\ServerException
|
||||
*/
|
||||
public function testInvalidSubscriptionThrowsServerException()
|
||||
{
|
||||
$parameters = array(
|
||||
'host' => REDIS_SERVER_HOST,
|
||||
'port' => REDIS_SERVER_PORT,
|
||||
'database' => REDIS_SERVER_DBNUM,
|
||||
'read_write_timeout' => -1, // -1 to set blocking reads
|
||||
);
|
||||
|
||||
$options = array('profile' => REDIS_SERVER_VERSION);
|
||||
|
||||
$consumer = new Client($parameters, $options);
|
||||
$consumer->connect();
|
||||
|
||||
$pubsub = $consumer->pubSubLoop();
|
||||
|
||||
// calling psubscribe with invalid empty parameter list
|
||||
$pubsub->psubscribe(array());
|
||||
|
||||
foreach ($pubsub as $message) {
|
||||
// should trigger the ServerException
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user