Files
OMS/app/taoexlib/lib/redis/redis.php
2025-12-28 23:13:25 +08:00

453 lines
8.8 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* Copyright © ShopeX http://www.shopex.cn. All rights reserved.
* See LICENSE file for license details.
*/
class taoexlib_redis_redis
{
private $host;
private $port;
private $handle;
/**
*
* @param string $host
* @param int $port
*/
public function __construct( $host = '127.0.0.1', $port = 6379 )
{
$this->host = $host;
$this->port = $port;
}
/**
* Ping server
*
* @param int $server_index Index of the server
*/
public function ping( $server_index )
{
return $this->execute_command($this->get_connection( $server_index ), 'PING');
}
# === Scalar operations ===
/**
* @param string $key
* @param mixed $value
*/
public function set( $key, $value )
{
$value = $this->pack_value($value);
$cmd = array("SET {$key} " . strlen($value), $value);
$response = $this->execute_command( $cmd );
return $this->get_error($response);
}
/**
* @param string $key
* @return mixed
*/
public function get( $key )
{
$response = $this->execute_command( "GET {$key}" );
if ( $this->get_error($response) )
{
return;
}
$length = (int)substr($response, 1);
if ( $length > 0 )
{
$value = $this->get_response();
return $this->unpack_value($value);
}
}
/**
* @param string $key
*/
public function delete( $key )
{
return $this->execute_command( "DEL {$key}" );
}
/**
* @param string $key
* @return boolean
*/
public function exists( $key )
{
return $this->execute_command( "EXISTS {$key}" ) == ':1';
}
/**
*
* @param string $key
* @param int $by
*/
public function inc( $key, $by = 1 )
{
$response = $this->execute_command( "INCRBY {$key} {$by}" );
return substr($response, 1);
}
/**
*
* @param string $key
* @param int $by
*/
public function dec( $key, $by = 1 )
{
$response = $this->execute_command( "DECRBY {$key} {$by}" );
return substr($response, 1);
}
# === List operations ===
public function prepend( $key, $value )
{
$value = $this->pack_value($value);
$cmd = array("LPUSH {$key} " . strlen($value), $value);
$response = $this->execute_command( $cmd );
return $this->get_error($response);
}
public function append( $key, $value )
{
$value = $this->pack_value($value);
$cmd = array("RPUSH {$key} " . $value);
$response = $this->execute_command( $cmd );
return $this->get_error($response);
}
public function lpop( $key ) {
$response = $this->execute_command( "LPOP {$key}");
if ( $this->get_error($response) )
{
return;
}
$length = (int)substr($response, 1);
if ( $length > 0 )
{
$value = $this->get_response();
return $this->unpack_value($value);
}
}
/**
* 获取_list
* @param mixed $key key
* @param mixed $limit limit
* @param mixed $offset offset
* @return mixed 返回结果
*/
public function get_list($key, $limit, $offset = 0)
{
$limit--;
$start = $offset;
$end = $start + $limit;
$response = $this->execute_command( "LRANGE {$key} {$start} {$end}" );
if ( $this->get_error($response) )
{
return;
}
$count = (int)substr($response, 1);
$list = array();
for ( $i = 0; $i < $count; $i++ )
{
$length = substr($this->get_response(), 1);
$value = $this->get_response();
$list[] = $this->unpack_value($value);
}
return $list;
}
/**
* 获取_filtered_list
* @param mixed $key key
* @param mixed $filters filters
* @param mixed $limit limit
* @param mixed $offset offset
* @return mixed 返回结果
*/
public function get_filtered_list($key, $filters, $limit = 0, $offset = 0)
{
$start = 0;
$end = $this->get_list_length($key);
$response = $this->execute_command( "LRANGE {$key} {$start} {$end}" );
if ( $this->get_error($response) )
{
return;
}
$limit = !$limit ? $end : $limit + $offset;
$list = array();
for ( $i = 0; $i < $end; $i++ )
{
$length = substr($this->get_response(), 1);
$value = $this->get_response();
$value = $this->unpack_value( $value );
if ( ( $filters == array_intersect($value, $filters) ) && ( ++$added <= $limit ) )
{
$list[] = $value;
}
}
$list = array_slice($list, $offset);
return $list;
}
/**
* 获取_list_length
* @param mixed $key key
* @return mixed 返回结果
*/
public function get_list_length($key)
{
$response = $this->execute_command( "LLEN {$key}" );
if ( $this->get_error($response) )
{
return;
}
return (int)substr($response, 1);
}
/**
* remove_from_list
* @param mixed $key key
* @param mixed $value value
* @param mixed $count count
* @return mixed 返回值
*/
public function remove_from_list($key, $value, $count = 0)
{
$value = $this->pack_value($value);
$response = $this->execute_command( array("LREM {$key} {$count} " . strlen($value), $value) );
if ( $this->get_error($response) )
{
return;
}
return (int)substr($response, 1);
}
/**
* remove_by_filter
* @param mixed $key key
* @param mixed $filters filters
* @return mixed 返回值
*/
public function remove_by_filter($key, $filters)
{
$list = $this->get_filtered_list($key, $filters);
foreach ( $list as $item )
{
$this->remove_from_list($key, $item);
}
}
/**
* truncate_list
* @param mixed $key key
* @param mixed $limit limit
* @param mixed $offset offset
* @return mixed 返回值
*/
public function truncate_list($key, $limit, $offset = 0)
{
$limit--;
$start = $offset;
$end = $start + $limit;
$response = $this->execute_command( "LTRIM {$key} {$start} {$end}" );
if ( $this->get_error($response) )
{
return;
}
return true;
}
# === Set operations ===
/**
* 添加_member
* @param mixed $key key
* @param mixed $value value
* @return mixed 返回值
*/
public function add_member( $key, $value )
{
$value = $this->pack_value($value);
$cmd = array("SADD {$key} " . strlen($value), $value);
$response = $this->execute_command( $cmd );
return $response == ':1';
}
/**
* remove_member
* @param mixed $key key
* @param mixed $value value
* @return mixed 返回值
*/
public function remove_member( $key, $value )
{
$value = $this->pack_value($value);
$cmd = array("SREM {$key} " . strlen($value), $value);
$response = $this->execute_command( $cmd );
return $response == ':1';
}
/**
* is_member
* @param mixed $key key
* @param mixed $value value
* @return mixed 返回值
*/
public function is_member( $key, $value )
{
$value = $this->pack_value($value);
$cmd = array("SISMEMBER {$key} " . strlen($value), $value);
$response = $this->execute_command( $cmd );
return $response == ':1';
}
/**
* 获取_members
* @param mixed $key key
* @return mixed 返回结果
*/
public function get_members($key)
{
$response = $this->execute_command( "SMEMBERS {$key}" );
if ( $this->get_error($response) )
{
return;
}
$count = (int)substr($response, 1);
$list = array();
for ( $i = 0; $i < $count; $i++ )
{
$length = substr($this->get_response(), 1);
$value = $this->get_response();
$list[] = $this->unpack_value($value);
}
return $list;
}
/**
* 获取_members_count
* @param mixed $key key
* @return mixed 返回结果
*/
public function get_members_count($key)
{
$response = $this->execute_command( "SCARD {$key}" );
if ( $this->get_error($response) )
{
return;
}
return (int)substr($response, 1);
}
# === Middle tier ===
/**
* Init connection
*/
private function get_connection()
{
if ( !$this->handle )
{
if ( !$sock = fsockopen($this->host, $this->port, $errno, $errstr) )
{
return false;
}
$this->handle = $sock;
}
return $this->handle;
}
private function pack_value( $value )
{
if ( is_numeric($value) )
{
return $value;
}
else
{
return base64_encode(serialize($value));
}
}
private function unpack_value( $packed )
{
if ( is_numeric($packed) )
{
return $packed;
}
return unserialize(base64_decode($packed));
}
private function execute_command( $commands )
{
$this->get_connection();
if ( !$this->handle ) return false;
if ( is_array($commands) )
{
$commands = implode("\r\n", $commands);
}
$command = $commands . "\r\n";
for ( $written = 0; $written < strlen($command); $written += $fwrite )
{
if ( !$fwrite = fwrite($this->handle, substr($command, $written)) )
{
return false;
}
}
return $this->get_response();
}
private function get_response()
{
if ( !$this->handle ) return false;
return trim(fgets($this->handle), "\r\n ");
}
private function get_error( $response )
{
if ( strpos($response, '-ERR') === 0 )
{
return substr($response, 5);
}
return false;
}
}