mirror of
https://gitee.com/ShopeX/OMS
synced 2026-03-31 05:25:32 +08:00
464 lines
9.2 KiB
PHP
464 lines
9.2 KiB
PHP
<?php
|
|
/**
|
|
* Copyright 2026 ShopeX (https://www.shopex.cn)
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
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;
|
|
}
|
|
} |