mirror of
https://github.com/predis/predis.git
synced 2026-08-17 19:45:45 +00:00
Compare commits
30 Commits
v2.4.0-RC1
...
v1.1.9
| Author | SHA1 | Date | |
|---|---|---|---|
| c50c3393bb | |||
| 4aa3014bb0 | |||
| 92adf32e88 | |||
| c4560304cf | |||
| cf5c118a07 | |||
| bb9a670c83 | |||
| 3e56e880e8 | |||
| 1c71a4e36e | |||
| 5004f5d6fc | |||
| e616f85679 | |||
| 9cd093be24 | |||
| 305d167b08 | |||
| 3271e1edcb | |||
| b240daa106 | |||
| 8fee6ce8c3 | |||
| 35dd44b222 | |||
| 545177f09f | |||
| 2f9337cb9b | |||
| 437d80a7a3 | |||
| 3a14a39d92 | |||
| 5c9457cc2e | |||
| c551fc21f9 | |||
| 0d84606723 | |||
| c021e380d6 | |||
| 5f4b87080f | |||
| 5ae4ac6b49 | |||
| 521ac8f0eb | |||
| fbbef2a0a2 | |||
| 9930e933c6 | |||
| 16957f3b39 |
+8
-2
@@ -1,18 +1,23 @@
|
||||
language: php
|
||||
sudo: false
|
||||
|
||||
branches:
|
||||
except:
|
||||
- v0.5
|
||||
- v0.6
|
||||
- v0.6-PHP_5.2
|
||||
- documentation
|
||||
|
||||
before_install:
|
||||
- docker run -d --rm -p 127.0.0.1:6379:6379 redis:3
|
||||
|
||||
before_script:
|
||||
- phpenv config-rm xdebug.ini
|
||||
- composer self-update
|
||||
- composer install --no-interaction --prefer-source --dev
|
||||
|
||||
script:
|
||||
- travis_retry vendor/bin/phpunit -c phpunit.xml.travisci
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
include:
|
||||
@@ -30,6 +35,7 @@ matrix:
|
||||
- php: 7.2
|
||||
- php: 7.3
|
||||
- php: 7.4
|
||||
- php: nightly # PHP 8.0.0-dev
|
||||
- php: 8.0
|
||||
- php: nightly
|
||||
allow_failures:
|
||||
- php: nightly
|
||||
|
||||
+33
-2
@@ -1,7 +1,38 @@
|
||||
v1.1.9 (2021-10-05)
|
||||
================================================================================
|
||||
|
||||
- Fixed PHP 8.1 compatibility in `StreamConnection`
|
||||
|
||||
|
||||
v1.1.8 (2021-09-29)
|
||||
================================================================================
|
||||
|
||||
- Ensure compatibility with PHP 8.1.
|
||||
|
||||
|
||||
v1.1.7 (2021-04-04)
|
||||
================================================================================
|
||||
|
||||
- __FIX__: with the phpiredis-based connection backends, failed pipelines led to
|
||||
spurious responses returned after reconnecting to Redis because the underlying
|
||||
reader was not properly reset by discarding buffered replies after disconnecting
|
||||
(ISSUE #363).
|
||||
- __FIX__: removed `cweagans/composer-patches` dev dependency and apply patches
|
||||
using `post-update-cmd` script.
|
||||
|
||||
|
||||
v1.1.6 (2020-09-11)
|
||||
================================================================================
|
||||
|
||||
- __FIX__: reverted support for sentinels authentication implemented in v1.1.5
|
||||
as it was bugged (see ISSUE #658), sorry for the trouble. This is now postponed
|
||||
as it requires a more thorough investigation.
|
||||
|
||||
|
||||
v1.1.5 (2020-09-10)
|
||||
================================================================================
|
||||
|
||||
- __FIX__: authentication for sentinels is now supported, previously it was not
|
||||
- __FIX__:~~authentication for sentinels is now supported, previously it was not
|
||||
possible to specify a `password` for sentinels as its value was stripped during
|
||||
initialization because sentinels did not support authentication until Redis 5.
|
||||
**Please note** that with the current implementation each sentinel must have
|
||||
@@ -9,7 +40,7 @@ its own `password` parameter set in the parameters list despite this password is
|
||||
the same for all sentinels (read how `requirepass` works on the Redis docs). In
|
||||
this case you should avoid using the global `parameters` client option used to
|
||||
set default parameters for every connection created by Predis as this would end
|
||||
up using the same password even when connecting to actual Redis nodes.
|
||||
up using the same password even when connecting to actual Redis nodes.~~
|
||||
|
||||
- __FIX__: the username is now correctly retrieved from the userinfo fragment of
|
||||
the URI when using the "redis" scheme and a "username:password" pair is present.
|
||||
|
||||
+4
-14
@@ -31,8 +31,7 @@
|
||||
"php": ">=5.3.9"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.8",
|
||||
"cweagans/composer-patches": "^1.6"
|
||||
"phpunit/phpunit": "~4.8"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-phpiredis": "Allows faster serialization and deserialization of the Redis protocol",
|
||||
@@ -43,16 +42,7 @@
|
||||
"Predis\\": "src/"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"composer-exit-on-patch-failure": true,
|
||||
"patches": {
|
||||
"phpunit/phpunit-mock-objects": {
|
||||
"Fix PHP 7 and 8 compatibility": "./tests/phpunit_mock_objects.patch"
|
||||
},
|
||||
"phpunit/phpunit": {
|
||||
"Fix PHP 7 compatibility": "./tests/phpunit_php7.patch",
|
||||
"Fix PHP 8 compatibility": "./tests/phpunit_php8.patch"
|
||||
}
|
||||
}
|
||||
}
|
||||
"scripts": {
|
||||
"post-update-cmd": "@php -f tests/apply-patches.php"
|
||||
}
|
||||
}
|
||||
|
||||
+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.6"
|
||||
stability = "devel"
|
||||
version = "1.1.9"
|
||||
stability = "stable"
|
||||
channel = "pear.nrk.io"
|
||||
|
||||
author = "Daniele Alessandri \"nrk\" <suppakilla@gmail.com>"
|
||||
|
||||
@@ -36,10 +36,6 @@
|
||||
</whitelist>
|
||||
</filter>
|
||||
|
||||
<logging>
|
||||
<log type="coverage-text" target="php://stdout" />
|
||||
</logging>
|
||||
|
||||
<php>
|
||||
<!-- Redis -->
|
||||
<const name="REDIS_SERVER_VERSION" value="3.2" />
|
||||
|
||||
+3
-2
@@ -40,7 +40,7 @@ use Predis\Transaction\MultiExec as MultiExecTransaction;
|
||||
*/
|
||||
class Client implements ClientInterface, \IteratorAggregate
|
||||
{
|
||||
const VERSION = '1.1.6-dev';
|
||||
const VERSION = '1.1.9';
|
||||
|
||||
protected $connection;
|
||||
protected $options;
|
||||
@@ -527,8 +527,9 @@ class Client implements ClientInterface, \IteratorAggregate
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return \Traversable<string, static>
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function getIterator()
|
||||
{
|
||||
$clients = array();
|
||||
|
||||
@@ -92,7 +92,7 @@ abstract class CursorBasedIterator implements \Iterator
|
||||
{
|
||||
$options = array();
|
||||
|
||||
if (strlen($this->match) > 0) {
|
||||
if (strlen(strval($this->match)) > 0) {
|
||||
$options['MATCH'] = $this->match;
|
||||
}
|
||||
|
||||
@@ -139,6 +139,7 @@ abstract class CursorBasedIterator implements \Iterator
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function rewind()
|
||||
{
|
||||
$this->reset();
|
||||
@@ -148,6 +149,7 @@ abstract class CursorBasedIterator implements \Iterator
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function current()
|
||||
{
|
||||
return $this->current;
|
||||
@@ -156,6 +158,7 @@ abstract class CursorBasedIterator implements \Iterator
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function key()
|
||||
{
|
||||
return $this->position;
|
||||
@@ -164,6 +167,7 @@ abstract class CursorBasedIterator implements \Iterator
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function next()
|
||||
{
|
||||
tryFetch: {
|
||||
@@ -184,6 +188,7 @@ abstract class CursorBasedIterator implements \Iterator
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function valid()
|
||||
{
|
||||
return $this->valid;
|
||||
|
||||
@@ -128,6 +128,7 @@ class ListKey implements \Iterator
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function rewind()
|
||||
{
|
||||
$this->reset();
|
||||
@@ -137,6 +138,7 @@ class ListKey implements \Iterator
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function current()
|
||||
{
|
||||
return $this->current;
|
||||
@@ -145,6 +147,7 @@ class ListKey implements \Iterator
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function key()
|
||||
{
|
||||
return $this->position;
|
||||
@@ -153,6 +156,7 @@ class ListKey implements \Iterator
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function next()
|
||||
{
|
||||
if (!$this->elements && $this->fetchmore) {
|
||||
@@ -169,6 +173,7 @@ class ListKey implements \Iterator
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function valid()
|
||||
{
|
||||
return $this->valid;
|
||||
|
||||
@@ -104,7 +104,7 @@ abstract class Command implements CommandInterface
|
||||
*/
|
||||
public static function normalizeArguments(array $arguments)
|
||||
{
|
||||
if (count($arguments) === 1 && is_array($arguments[0])) {
|
||||
if (count($arguments) === 1 && isset($arguments[0]) && is_array($arguments[0])) {
|
||||
return $arguments[0];
|
||||
}
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ class ProcessorChain implements \ArrayAccess, ProcessorInterface
|
||||
/**
|
||||
* Returns an iterator over the list of command processor in the chain.
|
||||
*
|
||||
* @return \ArrayIterator
|
||||
* @return \Traversable<int, ProcessorInterface>
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
@@ -89,8 +89,9 @@ class ProcessorChain implements \ArrayAccess, ProcessorInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return bool
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetExists($index)
|
||||
{
|
||||
return isset($this->processors[$index]);
|
||||
@@ -99,6 +100,7 @@ class ProcessorChain implements \ArrayAccess, ProcessorInterface
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetGet($index)
|
||||
{
|
||||
return $this->processors[$index];
|
||||
@@ -107,6 +109,7 @@ class ProcessorChain implements \ArrayAccess, ProcessorInterface
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetSet($index, $processor)
|
||||
{
|
||||
if (!$processor instanceof ProcessorInterface) {
|
||||
@@ -122,6 +125,7 @@ class ProcessorChain implements \ArrayAccess, ProcessorInterface
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetUnset($index)
|
||||
{
|
||||
unset($this->processors[$index]);
|
||||
|
||||
@@ -31,7 +31,10 @@ class ServerSentinel extends Command
|
||||
*/
|
||||
public function parseResponse($data)
|
||||
{
|
||||
switch (strtolower($this->getArgument(0))) {
|
||||
$argument = $this->getArgument(0);
|
||||
$argument = is_null($argument) ? null : strtolower($argument);
|
||||
|
||||
switch ($argument) {
|
||||
case 'masters':
|
||||
case 'slaves':
|
||||
return self::processMastersOrSlaves($data);
|
||||
|
||||
@@ -34,7 +34,12 @@ abstract class CommunicationException extends PredisException
|
||||
$code = null,
|
||||
\Exception $innerException = null
|
||||
) {
|
||||
parent::__construct($message, $code, $innerException);
|
||||
parent::__construct(
|
||||
is_null($message) ? '' : $message,
|
||||
is_null($code) ? 0 : $code,
|
||||
$innerException
|
||||
);
|
||||
|
||||
$this->connection = $connection;
|
||||
}
|
||||
|
||||
|
||||
@@ -176,16 +176,18 @@ class PredisCluster implements ClusterInterface, \IteratorAggregate, \Countable
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return int
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function count()
|
||||
{
|
||||
return count($this->pool);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return \Traversable<string|int, NodeConnectionInterface>
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function getIterator()
|
||||
{
|
||||
return new \ArrayIterator($this->pool);
|
||||
|
||||
@@ -600,16 +600,18 @@ class RedisCluster implements ClusterInterface, \IteratorAggregate, \Countable
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return int
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function count()
|
||||
{
|
||||
return count($this->pool);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return \Traversable<int, NodeConnectionInterface>
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function getIterator()
|
||||
{
|
||||
if ($this->useClusterSlots) {
|
||||
|
||||
@@ -146,14 +146,14 @@ class SentinelReplication implements ReplicationInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the time to wait (in seconds) before fetching a new configuration
|
||||
* Sets the time to wait (in milliseconds) before fetching a new configuration
|
||||
* from one of the sentinels.
|
||||
*
|
||||
* @param float $seconds Time to wait before the next attempt.
|
||||
* @param float $milliseconds Time to wait before the next attempt.
|
||||
*/
|
||||
public function setRetryWait($seconds)
|
||||
public function setRetryWait($milliseconds)
|
||||
{
|
||||
$this->retryWait = (float) $seconds;
|
||||
$this->retryWait = (float) $milliseconds;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -239,12 +239,15 @@ class SentinelReplication implements ReplicationInterface
|
||||
}
|
||||
|
||||
if (is_array($parameters)) {
|
||||
// Password authentication is fine now that Redis Sentinel supports
|
||||
// password-protected sentinel instances, but we must explicitly set
|
||||
// "database" and "username" to NULL so that no augmented AUTH (ACL)
|
||||
// and SELECT command are sent by accident to the sentinels.
|
||||
// NOTE: sentinels do not accept AUTH and SELECT commands so we must
|
||||
// explicitly set them to NULL to avoid problems when using default
|
||||
// parameters set via client options. Actually AUTH is supported for
|
||||
// sentinels starting with Redis 5 but we have to differentiate from
|
||||
// sentinels passwords and nodes passwords, this will be implemented
|
||||
// in a later release.
|
||||
$parameters['database'] = null;
|
||||
$parameters['username'] = null;
|
||||
$parameters['password'] = null;
|
||||
|
||||
if (!isset($parameters['timeout'])) {
|
||||
$parameters['timeout'] = $this->sentinelTimeout;
|
||||
|
||||
@@ -66,9 +66,9 @@ class PhpiredisSocketConnection extends AbstractConnection
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
phpiredis_reader_destroy($this->reader);
|
||||
|
||||
parent::__destruct();
|
||||
|
||||
phpiredis_reader_destroy($this->reader);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -227,9 +227,7 @@ class PhpiredisSocketConnection extends AbstractConnection
|
||||
$protocol = SOL_TCP;
|
||||
}
|
||||
|
||||
$socket = @socket_create($domain, SOCK_STREAM, $protocol);
|
||||
|
||||
if (!is_resource($socket)) {
|
||||
if (false === $socket = @socket_create($domain, SOCK_STREAM, $protocol)) {
|
||||
$this->emitSocketError();
|
||||
}
|
||||
|
||||
@@ -344,7 +342,9 @@ class PhpiredisSocketConnection extends AbstractConnection
|
||||
public function disconnect()
|
||||
{
|
||||
if ($this->isConnected()) {
|
||||
phpiredis_reader_reset($this->reader);
|
||||
socket_close($this->getResource());
|
||||
|
||||
parent::disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,9 +67,19 @@ class PhpiredisStreamConnection extends StreamConnection
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
phpiredis_reader_destroy($this->reader);
|
||||
|
||||
parent::__destruct();
|
||||
|
||||
phpiredis_reader_destroy($this->reader);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function disconnect()
|
||||
{
|
||||
phpiredis_reader_reset($this->reader);
|
||||
|
||||
parent::disconnect();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -387,7 +387,7 @@ class StreamConnection extends AbstractConnection
|
||||
$buffer = "*{$reqlen}\r\n\${$cmdlen}\r\n{$commandID}\r\n";
|
||||
|
||||
foreach ($arguments as $argument) {
|
||||
$arglen = strlen($argument);
|
||||
$arglen = strlen(strval($argument));
|
||||
$buffer .= "\${$arglen}\r\n{$argument}\r\n";
|
||||
}
|
||||
|
||||
|
||||
@@ -91,6 +91,7 @@ class Consumer implements \Iterator
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function rewind()
|
||||
{
|
||||
// NOOP
|
||||
@@ -101,6 +102,7 @@ class Consumer implements \Iterator
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function current()
|
||||
{
|
||||
return $this->getValue();
|
||||
@@ -109,6 +111,7 @@ class Consumer implements \Iterator
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function key()
|
||||
{
|
||||
return $this->position;
|
||||
@@ -117,6 +120,7 @@ class Consumer implements \Iterator
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function next()
|
||||
{
|
||||
++$this->position;
|
||||
@@ -127,6 +131,7 @@ class Consumer implements \Iterator
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function valid()
|
||||
{
|
||||
return $this->valid;
|
||||
|
||||
@@ -151,6 +151,7 @@ abstract class AbstractConsumer implements \Iterator
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function rewind()
|
||||
{
|
||||
// NOOP
|
||||
@@ -162,6 +163,7 @@ abstract class AbstractConsumer implements \Iterator
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function current()
|
||||
{
|
||||
return $this->getValue();
|
||||
@@ -170,6 +172,7 @@ abstract class AbstractConsumer implements \Iterator
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function key()
|
||||
{
|
||||
return $this->position;
|
||||
@@ -178,6 +181,7 @@ abstract class AbstractConsumer implements \Iterator
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function next()
|
||||
{
|
||||
if ($this->valid()) {
|
||||
@@ -192,6 +196,7 @@ abstract class AbstractConsumer implements \Iterator
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function valid()
|
||||
{
|
||||
$isValid = $this->isFlagSet(self::STATUS_VALID);
|
||||
|
||||
@@ -62,7 +62,8 @@ class ReplicationStrategy
|
||||
}
|
||||
|
||||
if (($eval = $id === 'EVAL') || $id === 'EVALSHA') {
|
||||
$sha1 = $eval ? sha1($command->getArgument(0)) : $command->getArgument(0);
|
||||
$argument = $command->getArgument(0);
|
||||
$sha1 = $eval ? sha1(strval($argument)) : $argument;
|
||||
|
||||
if (isset($this->readonlySHA1[$sha1])) {
|
||||
if (true === $readonly = $this->readonlySHA1[$sha1]) {
|
||||
|
||||
@@ -34,6 +34,7 @@ abstract class MultiBulkIterator implements \Iterator, \Countable, ResponseInter
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function rewind()
|
||||
{
|
||||
// NOOP
|
||||
@@ -42,6 +43,7 @@ abstract class MultiBulkIterator implements \Iterator, \Countable, ResponseInter
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function current()
|
||||
{
|
||||
return $this->current;
|
||||
@@ -50,6 +52,7 @@ abstract class MultiBulkIterator implements \Iterator, \Countable, ResponseInter
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function key()
|
||||
{
|
||||
return $this->position;
|
||||
@@ -58,6 +61,7 @@ abstract class MultiBulkIterator implements \Iterator, \Countable, ResponseInter
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function next()
|
||||
{
|
||||
if (++$this->position < $this->size) {
|
||||
@@ -68,6 +72,7 @@ abstract class MultiBulkIterator implements \Iterator, \Countable, ResponseInter
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function valid()
|
||||
{
|
||||
return $this->position < $this->size;
|
||||
@@ -82,6 +87,7 @@ abstract class MultiBulkIterator implements \Iterator, \Countable, ResponseInter
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function count()
|
||||
{
|
||||
return $this->size;
|
||||
|
||||
@@ -61,6 +61,7 @@ class MultiBulkTuple extends MultiBulk implements \OuterIterator
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function getInnerIterator()
|
||||
{
|
||||
return $this->iterator;
|
||||
|
||||
@@ -29,7 +29,7 @@ class AbortedMultiExecException extends PredisException
|
||||
*/
|
||||
public function __construct(MultiExec $transaction, $message, $code = null)
|
||||
{
|
||||
parent::__construct($message, $code);
|
||||
parent::__construct($message, is_null($code) ? 0 : $code);
|
||||
$this->transaction = $transaction;
|
||||
}
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ class ConnectionSelectTest extends PredisCommandTestCase
|
||||
/**
|
||||
* @group connected
|
||||
* @expectedException \Predis\Response\ServerException
|
||||
* @expectedExceptionMessage ERR invalid DB index
|
||||
* @expectedExceptionMessageRegExp /ERR (invalid DB index|value is not)/
|
||||
*/
|
||||
public function testThrowsExceptionOnUnexpectedDatabaseName()
|
||||
{
|
||||
|
||||
@@ -82,7 +82,7 @@ class KeyMoveTest extends PredisCommandTestCase
|
||||
/**
|
||||
* @group connected
|
||||
* @expectedException \Predis\Response\ServerException
|
||||
* @expectedExceptionMessage ERR index out of range
|
||||
* @expectedExceptionMessageRegEx /ERR.*out of range/
|
||||
*/
|
||||
public function testThrowsExceptionOnInvalidDatabases()
|
||||
{
|
||||
|
||||
@@ -66,6 +66,10 @@ class ReplicationOptionTest extends PredisTestCase
|
||||
*/
|
||||
public function testDoesNotAcceptValuesThatCanBeInterpretedAsBooleanFalse($value)
|
||||
{
|
||||
if (version_compare(PHP_VERSION, '5.4', '<')) {
|
||||
$this->markTestSkipped('Skip test, because.');
|
||||
}
|
||||
|
||||
$option = new ReplicationOption();
|
||||
$options = $this->getMock('Predis\Configuration\OptionsInterface');
|
||||
|
||||
|
||||
@@ -36,29 +36,19 @@ class SentinelReplicationTest extends PredisTestCase
|
||||
/**
|
||||
* @group disconnected
|
||||
*/
|
||||
public function testParametersForSentinelConnectionShouldUsePasswordForAuthentication()
|
||||
public function testParametersForSentinelConnectionShouldNotUseDatabaseAndUsernameAndPassword()
|
||||
{
|
||||
$replication = $this->getReplicationConnection('svc', array(
|
||||
'tcp://127.0.0.1:5381?alias=sentinel1&password=secret',
|
||||
'tcp://127.0.0.1:5381?alias=sentinel1&database=1&username=myusername&password=secret',
|
||||
));
|
||||
|
||||
$parameters = $replication->getSentinelConnection()->getParameters()->toArray();
|
||||
|
||||
$this->assertArraySubset(array('password' => 'secret'), $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group disconnected
|
||||
*/
|
||||
public function testParametersForSentinelConnectionShouldNotUseDatabaseAndUsername()
|
||||
{
|
||||
$replication = $this->getReplicationConnection('svc', array(
|
||||
'tcp://127.0.0.1:5381?alias=sentinel1&database=1&username=myusername',
|
||||
));
|
||||
|
||||
$parameters = $replication->getSentinelConnection()->getParameters()->toArray();
|
||||
|
||||
$this->assertArraySubset(array('database' => null, 'username' => null), $parameters);
|
||||
$this->assertArraySubset(array(
|
||||
'database' => null,
|
||||
'username' => null,
|
||||
'password' => null
|
||||
), $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -76,6 +76,28 @@ class PhpiredisSocketConnectionTest extends PredisConnectionTestCase
|
||||
// ---- INTEGRATION TESTS --------------------------------------------- //
|
||||
// ******************************************************************** //
|
||||
|
||||
/**
|
||||
* @group connected
|
||||
*/
|
||||
public function testClearsPendingResponsesInReaderBufferOnDisconnect()
|
||||
{
|
||||
$profile = $this->getCurrentProfile();
|
||||
$connection = $this->createConnection();
|
||||
|
||||
$cmdECHOBefore = $profile->createCommand('echo', array('BEFORE DISCONNECT'));
|
||||
$cmdECHOAfter = $profile->createCommand('echo', array('AFTER DISCONNECT'));
|
||||
|
||||
$connection->writeRequest($cmdECHOBefore);
|
||||
$connection->writeRequest($cmdECHOBefore);
|
||||
$connection->writeRequest($cmdECHOBefore);
|
||||
$connection->readResponse($cmdECHOBefore);
|
||||
$connection->disconnect();
|
||||
|
||||
$response = $connection->executeCommand($cmdECHOAfter);
|
||||
|
||||
$this->assertSame('AFTER DISCONNECT', $response);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group connected
|
||||
* @expectedException \Predis\Connection\ConnectionException
|
||||
|
||||
@@ -76,6 +76,28 @@ class PhpiredisStreamConnectionTest extends PredisConnectionTestCase
|
||||
// ---- INTEGRATION TESTS --------------------------------------------- //
|
||||
// ******************************************************************** //
|
||||
|
||||
/**
|
||||
* @group connected
|
||||
*/
|
||||
public function testClearsPendingResponsesInReaderBufferOnDisconnect()
|
||||
{
|
||||
$profile = $this->getCurrentProfile();
|
||||
$connection = $this->createConnection();
|
||||
|
||||
$cmdECHOBefore = $profile->createCommand('echo', array('BEFORE DISCONNECT'));
|
||||
$cmdECHOAfter = $profile->createCommand('echo', array('AFTER DISCONNECT'));
|
||||
|
||||
$connection->writeRequest($cmdECHOBefore);
|
||||
$connection->writeRequest($cmdECHOBefore);
|
||||
$connection->writeRequest($cmdECHOBefore);
|
||||
$connection->readResponse($cmdECHOBefore);
|
||||
$connection->disconnect();
|
||||
|
||||
$response = $connection->executeCommand($cmdECHOAfter);
|
||||
|
||||
$this->assertSame('AFTER DISCONNECT', $response);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group connected
|
||||
* @group slow
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
/**
|
||||
* Apply patches to support newer PHP versions.
|
||||
*/
|
||||
|
||||
$patches = array(
|
||||
'phpunit_mock_objects.patch' => 'phpunit/phpunit-mock-objects',
|
||||
'phpunit_php7.patch' => 'phpunit/phpunit',
|
||||
'phpunit_php8.patch' => 'phpunit/phpunit',
|
||||
'phpunit_php81.patch' => 'phpunit/phpunit',
|
||||
);
|
||||
|
||||
foreach ($patches as $patch => $package) {
|
||||
chdir(__DIR__.'/../vendor/'.$package);
|
||||
passthru(sprintf('patch -p1 -f < ../../../tests/%s', $patch));
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
diff --git a/src/Util/Configuration.php b/src/Util/Configuration.php
|
||||
index b2f7a7bd0c6..1a1a444d378 100644
|
||||
--- a/src/Util/Configuration.php
|
||||
+++ b/src/Util/Configuration.php
|
||||
@@ -514,22 +514,17 @@ public function handlePHPConfiguration()
|
||||
|
||||
foreach (array('var', 'post', 'get', 'cookie', 'server', 'files', 'request') as $array) {
|
||||
// See https://github.com/sebastianbergmann/phpunit/issues/277
|
||||
- switch ($array) {
|
||||
- case 'var':
|
||||
- $target = &$GLOBALS;
|
||||
- break;
|
||||
-
|
||||
- case 'server':
|
||||
- $target = &$_SERVER;
|
||||
- break;
|
||||
-
|
||||
- default:
|
||||
- $target = &$GLOBALS['_' . strtoupper($array)];
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
foreach ($configuration[$array] as $name => $value) {
|
||||
- $target[$name] = $value;
|
||||
+ switch ($array) {
|
||||
+ case 'var':
|
||||
+ $GLOBALS[$name] = $value;
|
||||
+ break;
|
||||
+ case 'server':
|
||||
+ $_SERVER[$name] = $value;
|
||||
+ break;
|
||||
+ default:
|
||||
+ $GLOBALS['_' . strtoupper($array)][$name] = $value;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/Util/Getopt.php b/src/Util/Getopt.php
|
||||
index 370e97d73f8..5bd8553970b 100644
|
||||
--- a/src/Util/Getopt.php
|
||||
+++ b/src/Util/Getopt.php
|
||||
@@ -144,7 +144,7 @@ protected static function parseLongOption($arg, $long_options, &$opts, &$args)
|
||||
|
||||
if (substr($long_opt, -1) == '=') {
|
||||
if (substr($long_opt, -2) != '==') {
|
||||
- if (!strlen($opt_arg)) {
|
||||
+ if (null === $opt_arg || strlen($opt_arg) < 1) {
|
||||
$opt_arg = current($args);
|
||||
next($args);
|
||||
if (!($opt_arg)) {
|
||||
Reference in New Issue
Block a user