当前位置: 首页 > 后端技术 > PHP

Redis通信协议

时间:2023-03-29 21:09:10 PHP

Redis命令发送格式:*<参数个数>CRLF$<参数1的字节数>CRLF<参数1的数据>CRLF...$<参数N的字节数>CRLF<参数N的数据>CRLFwhereCRLF表示rn,例如:setnamewuzhc格式化输出:*3$3set$4name$5wuzhc描述:*开头,表示有多少个参数,例如*3表示有3个参数(set,name,wuzhc)以$开头,表示参数的字节长度,例如$3表示set有3个字节,$4表示name有4个字节每行rn结尾的通信协议为:*3\r\n$3\r\nset\r\n$4\r\nname\r\n$5\r\nwuzhc\r\nRedis回复状态回复(statusreply)的第一个字节是“+”,例如+OK\r\n错误的第一个字节reply(错误回复)第一个字节为“-”,例如-Nosuchkey\r\n整数reply(整数回复)的第一个字节为“:”,例如:1\r\n第一个字节为批量回复(bulkreply)一个字节是“$”,例如$5\r\nwuzhc\r\nmultibulkreply(多批量回复)的第一个字节是“*”,例如*2\r\n$5\r\nwuzhc\r\n$3r\nage\r\nPHP实现Redis客户端_socket=stream_socket_client("tcp://{$ip}:{$port}",$errno,$errstr,1,STREAM_CLIENT_CONNECT);如果(!$this->_socket){退出($errstr);}}/***执行redis命令*@param$command*@returnarray|bool|string*/publicfunctionexec($command){//汇编发送命令格式$command=$this->_execCommand($command);//向redis发送命令fwrite($this->_socket,$command);//解析redis响应内容return$this->_parseResponse();}/***改变字符为redis通信协议格式*例如mgetnameage格式为*3\r\n$4\r\nmget\r\n$4\r\nname\r\n$3\r\nage\r\n*@param$command*@returnbool|string*/私有函数_execCommand($command){$line='';$crlf="\r\n";$params=explode('',$command);如果(empty($params)){返回$line;}//参数数量$line.='*'.计数($参数)。$crlf;//组装每个参数foreach((array)$paramsas$param){$line.='$'.mb_strlen($param,'8bit').$cr如果;$line.=$param.$crlf;}返回$行;}/***解析redis回复*@returnarray|bool|string*/privatefunction_parseResponse(){$line=fgets($this->_socket);$type=$line[0];$msg=mb_substr($line,1,-2,'8bit');switch($type){//状态回复case'+':if($msg=='OK'||$msg=='PONG'){returntrue;}else{返回$msg;}//错误响应case'-':exit($msg);//整数响应case':':return$msg;//批量回复case'$'://$后跟数据字节数(长度)$line=fread($this->_socket,(int)$msg+2);//数据字节数+(\r\n)两个字节returnmb_substr($line,0,-2,'8bit');//去掉最后两个字节//multiplebatchreplycase'*'://*表示$data=[]之后有多少个参数;对于($i=0;$i<$msg;$i++){$data[]=$this->_parseResponse();}返回$数据;}}}//demo$client=newClient('127.0.0.1',6379);$client->exec('setnamewuzhc');$res=$client->exec('getname');var_dump($资源);