mirror of
https://github.com/idanoo/php-resque
synced 2025-07-01 13:42:22 +00:00
- Reformatted files to PSR2 standard
- Removed credis for native phpredis - Tidied up some docs - Setting up new travis.ci build
This commit is contained in:
parent
065d5a4c63
commit
ae84530132
30 changed files with 3724 additions and 2682 deletions
|
@ -1,270 +1,262 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Wrap Credis to add namespace support and various helper methods.
|
||||
* Set up phpredis connection
|
||||
*
|
||||
* @package Resque/Redis
|
||||
* @author Chris Boulton <chris@bigcommerce.com>
|
||||
* @license http://www.opensource.org/licenses/mit-license.php
|
||||
* @package Resque/Redis
|
||||
* @author Chris Boulton <chris@bigcommerce.com>
|
||||
* @license http://www.opensource.org/licenses/mit-license.php
|
||||
*/
|
||||
|
||||
class Resque_Redis
|
||||
{
|
||||
/**
|
||||
* Redis namespace
|
||||
* @var string
|
||||
*/
|
||||
private static $defaultNamespace = 'resque:';
|
||||
/**
|
||||
* Redis namespace
|
||||
* @var string
|
||||
*/
|
||||
private static $defaultNamespace = 'resque:';
|
||||
|
||||
/**
|
||||
* A default host to connect to
|
||||
*/
|
||||
const DEFAULT_HOST = 'localhost';
|
||||
/**
|
||||
* A default host to connect to
|
||||
*/
|
||||
const DEFAULT_HOST = 'localhost';
|
||||
|
||||
/**
|
||||
* The default Redis port
|
||||
*/
|
||||
const DEFAULT_PORT = 6379;
|
||||
/**
|
||||
* The default Redis port
|
||||
*/
|
||||
const DEFAULT_PORT = 6379;
|
||||
|
||||
/**
|
||||
* The default Redis Database number
|
||||
*/
|
||||
const DEFAULT_DATABASE = 0;
|
||||
/**
|
||||
* The default Redis Database number
|
||||
*/
|
||||
const DEFAULT_DATABASE = 0;
|
||||
|
||||
/**
|
||||
* @var array List of all commands in Redis that supply a key as their
|
||||
* first argument. Used to prefix keys with the Resque namespace.
|
||||
*/
|
||||
private $keyCommands = array(
|
||||
'exists',
|
||||
'del',
|
||||
'type',
|
||||
'keys',
|
||||
'expire',
|
||||
'ttl',
|
||||
'move',
|
||||
'set',
|
||||
'setex',
|
||||
'get',
|
||||
'getset',
|
||||
'setnx',
|
||||
'incr',
|
||||
'incrby',
|
||||
'decr',
|
||||
'decrby',
|
||||
'rpush',
|
||||
'lpush',
|
||||
'llen',
|
||||
'lrange',
|
||||
'ltrim',
|
||||
'lindex',
|
||||
'lset',
|
||||
'lrem',
|
||||
'lpop',
|
||||
'blpop',
|
||||
'rpop',
|
||||
'sadd',
|
||||
'srem',
|
||||
'spop',
|
||||
'scard',
|
||||
'sismember',
|
||||
'smembers',
|
||||
'srandmember',
|
||||
'zadd',
|
||||
'zrem',
|
||||
'zrange',
|
||||
'zrevrange',
|
||||
'zrangebyscore',
|
||||
'zcard',
|
||||
'zscore',
|
||||
'zremrangebyscore',
|
||||
'sort',
|
||||
'rename',
|
||||
'rpoplpush'
|
||||
);
|
||||
// sinterstore
|
||||
// sunion
|
||||
// sunionstore
|
||||
// sdiff
|
||||
// sdiffstore
|
||||
// sinter
|
||||
// smove
|
||||
// mget
|
||||
// msetnx
|
||||
// mset
|
||||
// renamenx
|
||||
/**
|
||||
* @var array List of all commands in Redis that supply a key as their
|
||||
* first argument. Used to prefix keys with the Resque namespace.
|
||||
*/
|
||||
private $keyCommands = [
|
||||
'exists',
|
||||
'del',
|
||||
'type',
|
||||
'keys',
|
||||
'expire',
|
||||
'ttl',
|
||||
'move',
|
||||
'set',
|
||||
'setex',
|
||||
'get',
|
||||
'getset',
|
||||
'setnx',
|
||||
'incr',
|
||||
'incrby',
|
||||
'decr',
|
||||
'decrby',
|
||||
'rpush',
|
||||
'lpush',
|
||||
'llen',
|
||||
'lrange',
|
||||
'ltrim',
|
||||
'lindex',
|
||||
'lset',
|
||||
'lrem',
|
||||
'lpop',
|
||||
'blpop',
|
||||
'rpop',
|
||||
'sadd',
|
||||
'srem',
|
||||
'spop',
|
||||
'scard',
|
||||
'sismember',
|
||||
'smembers',
|
||||
'srandmember',
|
||||
'zadd',
|
||||
'zrem',
|
||||
'zrange',
|
||||
'zrevrange',
|
||||
'zrangebyscore',
|
||||
'zcard',
|
||||
'zscore',
|
||||
'zremrangebyscore',
|
||||
'sort',
|
||||
'rename',
|
||||
'rpoplpush'
|
||||
];
|
||||
// sinterstore
|
||||
// sunion
|
||||
// sunionstore
|
||||
// sdiff
|
||||
// sdiffstore
|
||||
// sinter
|
||||
// smove
|
||||
// mget
|
||||
// msetnx
|
||||
// mset
|
||||
// renamenx
|
||||
|
||||
/**
|
||||
* Set Redis namespace (prefix) default: resque
|
||||
* @param string $namespace
|
||||
*/
|
||||
public static function prefix($namespace)
|
||||
{
|
||||
if (substr($namespace, -1) !== ':' && $namespace != '') {
|
||||
$namespace .= ':';
|
||||
}
|
||||
self::$defaultNamespace = $namespace;
|
||||
}
|
||||
/**
|
||||
* Set Redis namespace (prefix) default: resque
|
||||
* @param string $namespace
|
||||
*/
|
||||
public static function prefix($namespace)
|
||||
{
|
||||
if (substr($namespace, -1) !== ':' && $namespace != '') {
|
||||
$namespace .= ':';
|
||||
}
|
||||
self::$defaultNamespace = $namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|array $server A DSN or array
|
||||
* @param int $database A database number to select. However, if we find a valid database number in the DSN the
|
||||
* DSN-supplied value will be used instead and this parameter is ignored.
|
||||
* @param object $client Optional Credis_Cluster or Credis_Client instance instantiated by you
|
||||
*/
|
||||
/**
|
||||
* @param string|array $server A DSN or array
|
||||
* @param int $database A database number to select. However, if we find a valid database number in the DSN the
|
||||
* DSN-supplied value will be used instead and this parameter is ignored.
|
||||
* @param object $client Optional Credis_Cluster or Credis_Client instance instantiated by you
|
||||
* @throws Resque_RedisException
|
||||
*/
|
||||
public function __construct($server, $database = null, $client = null)
|
||||
{
|
||||
try {
|
||||
if (is_array($server)) {
|
||||
$this->driver = new Credis_Cluster($server);
|
||||
}
|
||||
else if (is_object($client)) {
|
||||
$this->driver = $client;
|
||||
}
|
||||
else {
|
||||
list($host, $port, $dsnDatabase, $user, $password, $options) = self::parseDsn($server);
|
||||
// $user is not used, only $password
|
||||
{
|
||||
try {
|
||||
if (is_object($client)) {
|
||||
$this->redisConnection = $client;
|
||||
} else {
|
||||
list($host, $port, $dsnDatabase, $user, $password, $options) = self::parseDsn($server);
|
||||
// $user is not used, only $password
|
||||
|
||||
// Look for known Credis_Client options
|
||||
$timeout = isset($options['timeout']) ? intval($options['timeout']) : null;
|
||||
$persistent = isset($options['persistent']) ? $options['persistent'] : '';
|
||||
$maxRetries = isset($options['max_connect_retries']) ? $options['max_connect_retries'] : 0;
|
||||
$timeout = isset($options['timeout']) ? intval($options['timeout']) : null;
|
||||
|
||||
$this->driver = new Credis_Client($host, $port, $timeout, $persistent);
|
||||
$this->driver->setMaxConnectRetries($maxRetries);
|
||||
if ($password){
|
||||
$this->driver->auth($password);
|
||||
}
|
||||
$this->redisConnection = new \Redis();
|
||||
|
||||
// If we have found a database in our DSN, use it instead of the `$database`
|
||||
// value passed into the constructor.
|
||||
if ($dsnDatabase !== false) {
|
||||
$database = $dsnDatabase;
|
||||
}
|
||||
}
|
||||
if (!$this->redisConnection->connect($host, $port, $timeout)) {
|
||||
throw new RedisException("Connection Failed to Redis!");
|
||||
};
|
||||
|
||||
if ($database !== null) {
|
||||
$this->driver->select($database);
|
||||
}
|
||||
}
|
||||
catch(CredisException $e) {
|
||||
throw new Resque_RedisException('Error communicating with Redis: ' . $e->getMessage(), 0, $e);
|
||||
}
|
||||
}
|
||||
if ($password) {
|
||||
$this->redisConnection->auth($password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a DSN string, which can have one of the following formats:
|
||||
*
|
||||
* - host:port
|
||||
* - redis://user:pass@host:port/db?option1=val1&option2=val2
|
||||
* - tcp://user:pass@host:port/db?option1=val1&option2=val2
|
||||
* - unix:///path/to/redis.sock
|
||||
*
|
||||
* Note: the 'user' part of the DSN is not used.
|
||||
*
|
||||
* @param string $dsn A DSN string
|
||||
* @return array An array of DSN compotnents, with 'false' values for any unknown components. e.g.
|
||||
* [host, port, db, user, pass, options]
|
||||
*/
|
||||
public static function parseDsn($dsn)
|
||||
{
|
||||
if ($dsn == '') {
|
||||
// Use a sensible default for an empty DNS string
|
||||
$dsn = 'redis://' . self::DEFAULT_HOST;
|
||||
}
|
||||
if(substr($dsn, 0, 7) === 'unix://') {
|
||||
return array(
|
||||
$dsn,
|
||||
null,
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
}
|
||||
$parts = parse_url($dsn);
|
||||
// If we have found a database in our DSN, use it instead of the `$database`
|
||||
// value passed into the constructor.
|
||||
if ($dsnDatabase !== false) {
|
||||
$database = $dsnDatabase;
|
||||
}
|
||||
|
||||
// Check the URI scheme
|
||||
$validSchemes = array('redis', 'tcp');
|
||||
if (isset($parts['scheme']) && ! in_array($parts['scheme'], $validSchemes)) {
|
||||
throw new \InvalidArgumentException("Invalid DSN. Supported schemes are " . implode(', ', $validSchemes));
|
||||
}
|
||||
if ($database) {
|
||||
$this->redisConnection->select($database);
|
||||
}
|
||||
}
|
||||
} catch (RedisException $e) {
|
||||
throw new Resque_RedisException('Error communicating with Redis: ' . $e->getMessage(), 0, $e);
|
||||
}
|
||||
}
|
||||
|
||||
// Allow simple 'hostname' format, which `parse_url` treats as a path, not host.
|
||||
if ( ! isset($parts['host']) && isset($parts['path'])) {
|
||||
$parts['host'] = $parts['path'];
|
||||
unset($parts['path']);
|
||||
}
|
||||
/**
|
||||
* Parse a DSN string, which can have one of the following formats:
|
||||
*
|
||||
* - host:port
|
||||
* - redis://user:pass@host:port/db?option1=val1&option2=val2
|
||||
* - tcp://user:pass@host:port/db?option1=val1&option2=val2
|
||||
* - unix:///path/to/redis.sock
|
||||
*
|
||||
* Note: the 'user' part of the DSN is not used.
|
||||
*
|
||||
* @param string $dsn A DSN string
|
||||
* @return array An array of DSN compotnents, with 'false' values for any unknown components. e.g.
|
||||
* [host, port, db, user, pass, options]
|
||||
*/
|
||||
public static function parseDsn($dsn)
|
||||
{
|
||||
if ($dsn == '') {
|
||||
// Use a sensible default for an empty DNS string
|
||||
$dsn = 'redis://' . self::DEFAULT_HOST;
|
||||
}
|
||||
if (substr($dsn, 0, 7) === 'unix://') {
|
||||
return [
|
||||
$dsn,
|
||||
null,
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
];
|
||||
}
|
||||
$parts = parse_url($dsn);
|
||||
|
||||
// Extract the port number as an integer
|
||||
$port = isset($parts['port']) ? intval($parts['port']) : self::DEFAULT_PORT;
|
||||
// Check the URI scheme
|
||||
$validSchemes = array('redis', 'tcp');
|
||||
if (isset($parts['scheme']) && !in_array($parts['scheme'], $validSchemes)) {
|
||||
throw new \InvalidArgumentException("Invalid DSN. Supported schemes are " . implode(', ', $validSchemes));
|
||||
}
|
||||
|
||||
// Get the database from the 'path' part of the URI
|
||||
$database = false;
|
||||
if (isset($parts['path'])) {
|
||||
// Strip non-digit chars from path
|
||||
$database = intval(preg_replace('/[^0-9]/', '', $parts['path']));
|
||||
}
|
||||
// Allow simple 'hostname' format, which `parse_url` treats as a path, not host.
|
||||
if (!isset($parts['host']) && isset($parts['path'])) {
|
||||
$parts['host'] = $parts['path'];
|
||||
unset($parts['path']);
|
||||
}
|
||||
|
||||
// Extract any 'user' and 'pass' values
|
||||
$user = isset($parts['user']) ? $parts['user'] : false;
|
||||
$pass = isset($parts['pass']) ? $parts['pass'] : false;
|
||||
// Extract the port number as an integer
|
||||
$port = isset($parts['port']) ? intval($parts['port']) : self::DEFAULT_PORT;
|
||||
|
||||
// Convert the query string into an associative array
|
||||
$options = array();
|
||||
if (isset($parts['query'])) {
|
||||
// Parse the query string into an array
|
||||
parse_str($parts['query'], $options);
|
||||
}
|
||||
// Get the database from the 'path' part of the URI
|
||||
$database = false;
|
||||
if (isset($parts['path'])) {
|
||||
// Strip non-digit chars from path
|
||||
$database = intval(preg_replace('/[^0-9]/', '', $parts['path']));
|
||||
}
|
||||
|
||||
return array(
|
||||
$parts['host'],
|
||||
$port,
|
||||
$database,
|
||||
$user,
|
||||
$pass,
|
||||
$options,
|
||||
);
|
||||
}
|
||||
// Extract any 'user' and 'pass' values
|
||||
$user = isset($parts['user']) ? $parts['user'] : false;
|
||||
$pass = isset($parts['pass']) ? $parts['pass'] : false;
|
||||
|
||||
/**
|
||||
* Magic method to handle all function requests and prefix key based
|
||||
* operations with the {self::$defaultNamespace} key prefix.
|
||||
*
|
||||
* @param string $name The name of the method called.
|
||||
* @param array $args Array of supplied arguments to the method.
|
||||
* @return mixed Return value from Resident::call() based on the command.
|
||||
*/
|
||||
public function __call($name, $args)
|
||||
{
|
||||
if (in_array($name, $this->keyCommands)) {
|
||||
if (is_array($args[0])) {
|
||||
foreach ($args[0] AS $i => $v) {
|
||||
$args[0][$i] = self::$defaultNamespace . $v;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$args[0] = self::$defaultNamespace . $args[0];
|
||||
}
|
||||
}
|
||||
try {
|
||||
return $this->driver->__call($name, $args);
|
||||
}
|
||||
catch (CredisException $e) {
|
||||
throw new Resque_RedisException('Error communicating with Redis: ' . $e->getMessage(), 0, $e);
|
||||
}
|
||||
}
|
||||
// Convert the query string into an associative array
|
||||
$options = array();
|
||||
if (isset($parts['query'])) {
|
||||
// Parse the query string into an array
|
||||
parse_str($parts['query'], $options);
|
||||
}
|
||||
|
||||
public static function getPrefix()
|
||||
{
|
||||
return self::$defaultNamespace;
|
||||
}
|
||||
return array(
|
||||
$parts['host'],
|
||||
$port,
|
||||
$database,
|
||||
$user,
|
||||
$pass,
|
||||
$options,
|
||||
);
|
||||
}
|
||||
|
||||
public static function removePrefix($string)
|
||||
{
|
||||
$prefix=self::getPrefix();
|
||||
/**
|
||||
* Magic method to handle all function requests and prefix key based
|
||||
* operations with the {self::$defaultNamespace} key prefix.
|
||||
*
|
||||
* @param string $name The name of the method called.
|
||||
* @param array $args Array of supplied arguments to the method.
|
||||
* @return mixed Return value from Resident::call() based on the command.
|
||||
*/
|
||||
public function __call($name, $args)
|
||||
{
|
||||
if (in_array($name, $this->keyCommands)) {
|
||||
if (is_array($args[0])) {
|
||||
foreach ($args[0] AS $i => $v) {
|
||||
$args[0][$i] = self::$defaultNamespace . $v;
|
||||
}
|
||||
} else {
|
||||
$args[0] = self::$defaultNamespace . $args[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (substr($string, 0, strlen($prefix)) == $prefix) {
|
||||
$string = substr($string, strlen($prefix), strlen($string) );
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
public static function getPrefix()
|
||||
{
|
||||
return self::$defaultNamespace;
|
||||
}
|
||||
|
||||
public static function removePrefix($string)
|
||||
{
|
||||
$prefix = self::getPrefix();
|
||||
|
||||
if (substr($string, 0, strlen($prefix)) == $prefix) {
|
||||
$string = substr($string, strlen($prefix), strlen($string));
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue