php redis 实例,php实现redis的服务端的示例

本文介绍了如何使用PHP实现一个简单的Redis服务端,该服务端仅支持SET和GET命令。通过解析RESP协议来处理客户端请求,代码中包含了多进程阻塞式处理。作者通过phpclnt_fork创建工作进程来监听并处理连接,并提供了测试PHP实现Redis性能的方法。这是一个理解Redis服务端和PHP网络编程的好例子。
摘要由CSDN通过智能技术生成

php实现redis就是像php与mysql数据库一样进行一些操作了,我们这里来看一篇关于php实现redis的服务端的示例吧,具体的细节如下文介绍。

大家都知道redis是用C来实现的,现在我用php来实现一个简单的仅支持SET和GET命令的redis服务端,主要是为了更好的了解redis的服务端和php的网络编程.

代码如下:

/**

* 多进程阻塞式

*/

class Xtgxiso_server

{

private $socket = false;

private $process_num = 100;

public $redis_kv_data = array();

public $onMessage = null;

function __construct($host="0.0.0.0",$port=1215)

{

$this->socket = stream_socket_server("tcp://".$host.":".$port,$errno, $errstr);

if (!$this->socket) die($errstr."--".$errno);

echo "listen $host $port \r\n";

ini_set("memory_limit", "128M");

}

private function parseRESP(&$conn){

$line = fgets($conn);

if($line === '' || $line === false)

{

return null;

}

$type = $line[0];

$line = mb_substr($line,1,-2);

switch ( $type ){

case "*":

$count = (int) $line;

$data = array();

for ($i = 1; $i <= $count; $i ) {

$data[] = $this->parseRESP($conn);

}

return $data;

case "$":

if ($line == '-1') {

return null;

}

$length = $line 2;

$data = '';

while ($length > 0) {

$block = fread($conn, $length);

if ($length !== strlen($block)) {

throw new Exception('RECEIVING');

}

$data .= $block;

$length -= mb_strlen($block);

}

return mb_substr($data, 0, -2);

}

return $line;

}

private function start_worker_process(){

$pid = pcntl_fork();

switch ($pid) {

case -1:

echo "fork error : {$i} \r\n";

exit;

case 0:

while ( 1 ) {

echo  "waiting...\n";

$conn = stream_socket_accept($this->socket, -1);

if ( !$conn ){

continue;

}

//"*3\r\n$3\r\nSET\r\n$5\r\nmykey\r\n$7\r\nmyvalue\r\n"

while(1){

$arr = $this->parseRESP($conn);

if ( is_array($arr) ) {

if ($this->onMessage) {

call_user_func($this->onMessage, $conn, $arr);

}

}else if ( $arr ){

if ($this->onMessage) {

call_user_func($this->onMessage, $conn, $arr);

}

}else{

fclose($conn);

break;

}

}

}

default:

$this->pids[$pid] = $pid;

break;

}

}

public function run(){

for($i = 1; $i <= $this->process_num; $i ){

$this->start_worker_process();

}

while(1){

foreach ($this->pids as $i => $pid) {

if($pid) {

$res = pcntl_waitpid($pid, $status,WNOHANG);

if ( $res == -1 || $res > 0 ){

$this->start_worker_process();

unset($this->pids[$pid]);

}

}

}

sleep(1);

}

}

}

$server =  new Xtgxiso_server();

$server->onMessage = function($conn,$info) use($server){

if ( is_array($info) ){

if ( $info["0"] == "SET" ) {

$key = $info[1];

$val = $info[2];

$server->redis_kv_data[$key] = $val;

fwrite($conn, " OK\r\n");

}else if ( $info["0"] == "GET" ){

$key = $info[1];

fwrite($conn, "$".strlen($server->redis_kv_data[$key])."\r\n".$server->redis_kv_data[$key]."\r\n");

}else{

fwrite($conn," OK\r\n");

}

}else{

fwrite($conn," OK\r\n");

}

};

$server->run();

通过如下命令来测试PHP实现的性能:

redis-benchmark -h 10.170.233.221 -p 1215 -t set -n 80000 -q

3bafdb3c0e07f5d80d3b6fb232811205.png

看来还是不错的,大家有兴趣可以再实现其他命令!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值