php语言实现redis的客户端

 更新时间:2016年11月25日 15:30  点击:5143
php语言实现redis的客户端与服务端有一些区别了因为前面介绍过服务端了这里我们来介绍客户端吧,希望文章对各位有帮助。

为了更好的了解redis协议,我们用php来实现一个支持大部份命令的客户端类.

redis的协议可参考这个文章http://redis.cn/topics/protocol.html

代码如下:

<?php
namespace xtgxiso;
class Redis {
    private $redis_socket = false;
    private $cmd = '';
    public function __construct($host='127.0.0.1',$port=6379,$timeout = 3) {
        $this->redis_socket = stream_socket_client("tcp://".$host.":".$port, $errno, $errstr,  $timeout);
        if ( !$this->redis_socket) {
            throw new Exception("{$errno} - {$errstr}");
        }
    }
    public function __destruct() {
        fclose($this->redis_socket);
    }
    public function __call($name, $args) {
        $crlf = "\r\n";
        array_unshift($args,$name);
        $command = '*' . count($args) . $crlf;
        foreach ($args as $arg) {
            $command .= '$' . strlen($arg) . $crlf . $arg . $crlf;
        }
        $fwrite = fwrite($this->redis_socket,$command);
        if ($fwrite === FALSE || $fwrite <= 0) {
            throw new Exception('Failed to write entire command to stream');
        }
        return $this->readResponse();
    }
    private function readResponse() {
        $reply = trim(fgets($this->redis_socket, 1024));
        switch (substr($reply, 0, 1)) {
            case '-':
                throw new Exception(trim(substr($reply, 4)));
                break;
            case '+':
                $response = substr(trim($reply), 1);
                if ($response === 'OK') {
                    $response = TRUE;
                }
                break;
            case '$':
                $response = NULL;
                if ($reply == '$-1') {
                    break;
                }
                $read = 0;
                $size = intval(substr($reply, 1));
                if ($size > 0) {
                    do {
                        $block_size = ($size - $read) > 1024 ? 1024 : ($size - $read);
                        $r = fread($this->redis_socket, $block_size);
                        if ($r === FALSE) {
                            throw new Exception('Failed to read response from stream');
                        } else {
                            $read += strlen($r);
                            $response .= $r;
                        }
                    } while ($read < $size);
                }
                fread($this->redis_socket, 2); /* discard crlf */
                break;
            /* Multi-bulk reply */
            case '*':
                $count = intval(substr($reply, 1));
                if ($count == '-1') {
                    return NULL;
                }
                $response = array();
                for ($i = 0; $i < $count; $i++) {
                    $response[] = $this->readResponse();
                }
                break;
            /* Integer reply */
            case ':':
                $response = intval(substr(trim($reply), 1));
                break;
            default:
                throw new RedisException("Unknown response: {$reply}");
                break;
        }
        return $response;
    }
}
/*
$redis = new Client_test();
var_dump($redis->auth("123456"));
var_dump($redis->set("xtgxiso",'abc'));
var_dump($redis->get("xtgxiso"));
*/
通过实现,我们基本了解redis的协议。

socket异步或同步的教程以前介绍过asp的今天我们看看php中socket编程方式的一篇教程,有兴趣的和小编来看这篇socket服务的模型下的编程方式(同步和异步)例子吧。

    前面我们花了一段时间来搭建高性能的socket服务,可以同时处理大量的连接,但这是在没有具体业务的情况下。

    如果我们启用了一个单进程的server,但里面的一个业务耗时1秒,那么在这1秒内是阻塞的,后续的请求会等待,如果并发三个请求,那么三个请求的执行时间会分别昌1秒,2秒,3秒.提高并发的方法有以下几种:

    1:多启动进程,提高并发数

    2:优化业务,减少耗时间相当于减少阻塞时间,提高并发数

    3:异步编程,避免阻塞,提高并发数

    这里我们重点介绍第三种方法,以访问第三方http为例。

    代码如下:

<?php
//同步读取
function get_data_blocking(){
    $socket = stream_socket_client("tcp://test.raventech.cn:80", $errno, $errstr, 6);
    fwrite($socket, "GET /sleep1.php HTTP/1.0\r\nHost: test.raventech.cn\r\nAccept: */*\r\n\r\n");
    $str = "";
    while (!feof($socket)) {
        $str .= fgets($socket, 1024);
    }
    fclose($socket);
    return $str;
}

//异步读取
function get_data_unblocking(){
    $socket = stream_socket_client("tcp://test.raventech.cn:80", $errno, $errstr, 6);
    stream_set_blocking($socket, 0);
    fwrite($socket, "GET /sleep1.php HTTP/1.0\r\nHost: test.raventech.cn\r\nAccept: */*\r\n\r\n");
    $write  = NULL;
    $except = NULL;
    while( $socket ){
        $read   = array($socket);
        $num_changed_streams = stream_select($read, $write, $except, 0);
        if ( $num_changed_streams > 0 ) {
            foreach($read as $r){
                $str = fread($r,2048);
                fclose($socket);
                $socket = false;
                return $str;
            }
        }
        usleep(100);
    }
}

//真正的异步读取--利用server的IO复用事件来提高并发
class Get_data_event{

    public $onMessage = null;
    private $str='';

    function __construct(&$server){
        $socket = stream_socket_client("tcp://test.xtgxiso.cn:80", $errno, $errstr, 6);
        stream_set_blocking($socket, 0);
        fwrite($socket, "GET /sleep1.php HTTP/1.0\r\nHost: test.xtgxiso.cn\r\nAccept: */*\r\n\r\n");
        $server->add_socket($socket, array($this, 'read'));
    }

    public function read($socket){
        while (1) {
            $buffer = fread($socket, 1024);
            if ($buffer === '' || $buffer === false) {
                break;
            }
            $this->str .= $buffer;
        }
        if( $this->onMessage && $this->str ) {
            call_user_func($this->onMessage, $this->str);
        }
        $this->str = '';
        return false;
    }

}

/**
 * 单进程IO复用select
 */
class Xtgxiso_server
{
    public $socket = false;
    public $master = array();
    public $onConnect = null;
    public $onMessage = null;
    public $other_socket_callback = array();

    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);
        stream_set_blocking($this->socket,0);
        $id = (int)$this->socket;
        $this->master[$id] = $this->socket;
    }

    public function add_socket($socket,$callback){
        $id = (int)$socket;
        $this->master[$id] = $socket;
        $this->other_socket_callback[$id] = $callback;
    }

    public function run(){
        $read = $this->master;
        $receive = array();
        echo  "start run...\n";
        while ( 1 ) {
            $read = $this->master;
            //echo  "waiting...\n";
            $mod_fd = @stream_select($read, $_w = NULL, $_e = NULL, 60);
            if ($mod_fd === FALSE) {
                break;
            }
            foreach ( $read as $k => $v ) {
                $id = (int)$v;
                if ( $v === $this->socket ) {
                    //echo "new conn\n";
                    $conn = stream_socket_accept($this->socket);
                    if ($this->onConnect) {
                        call_user_func($this->onConnect, $conn);
                    }
                    $id = (int)$conn;
                    $this->master[$id] = $conn;
                } else if ( @$this->other_socket_callback[$id] ){
                    call_user_func_array($this->other_socket_callback[$id], array($v));
                } else {
                    //echo "read data\n";
                    if ( !isset($receive[$k]) ){
                        $receive[$k]="";
                    }
                    $buffer = fread($v, 1024);
                    //echo $buffer."\n";
                    if ( strlen($buffer) === 0 ) {
                        if ( $this->onClose ){
                            call_user_func($this->onClose,$v);
                        }
                        fclose($v);
                        $id = (int)$v;
                        unset($this->master[$id]);
                    } else if ( $buffer === FALSE ) {
                        if ( $this->onClose ){
                            call_user_func($this->onClose, $this->master[$key_to_del]);
                        }
                        fclose($v);
                        $id = (int)$v;
                        unset($this->master[$id]);
                    } else {
                        $pos = strpos($buffer, "\r\n\r\n");
                        if ( $pos === false) {
                            $receive[$k] .= $buffer;
                            //echo "received:".$buffer.";not all package,continue recdiveing\n";
                        }else{
                            $receive[$k] .= trim(substr ($buffer,0,$pos+4));
                            $buffer = substr($buffer,$pos+4);
                            if($this->onMessage) {
                                call_user_func($this->onMessage,$v,$receive[$k]);
                            }
                            $receive[$k]='';
                        }
                    }
                }
            }
            usleep(10000);
        }
    }
}


$server =  new Xtgxiso_server();

$server->onConnect = function($conn){
    echo "onConnect -- accepted " . stream_socket_get_name($conn,true) . "\n";
};

$server->onMessage = function($conn,$msg) use ( $server ) {
    /*
    $respone ="";//响应内容
    $respone = "HTTP/1.1 200 OK\r\n";
    $respone .= "Server: openresty\r\n";
    $respone .= "Content-Type: text/html; charset=utf-8\r\n";
    $body = time().rand(111111,999999);
    $len = strlen($body);
    $respone .= "Content-Length:$len\r\n";
    $respone .= "Connection: close\r\n";
    $respone .= "\r\n$body\r\n\r\n";
    echo "onMessage --" . $msg . "\n";
    */

    //同步读取
    //$respone = get_data_blocking();
    //fwrite($conn,$respone);

    //异步读取
    //$respone = get_data_unblocking();
    //fwrite($conn,$respone);

    //真正异步
    $data = new Get_data_event($server);
    $data->onMessage = function($str) use($conn){
        fwrite($conn,$str);
    };

};

$server->onClose = function($conn){
    echo "onClose --" . "\n";
};

$server->run();
    第三方服务sleep1.php的代码比较简单

<?php
sleep(1);//模拟耗时
echo "OK";
    通过以上代码示例,我们分别注释运行 同步读取,异步读取,真正异步,来观察server的并发.测试方法可以写个test.html来模拟三个并发.

<script src="http://127.0.0.1:1215/?id=1"></script>
<script src="http://127.0.0.1:1215/?id=2"></script>
<script src="http://127.0.0.1:1215/?id=3"></script>
    通过测试发现,真正异步的是并发的,每个请求耗时1秒,这样我们总算明白什么是真正的非阻塞异步编程了,关键就在共用IO复用.

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

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

代码如下:

<?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

 


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

curl默认是不能访问https了如果要curl访问https我们需要进行一些参数配置了,下面我们来看一篇关于php curl访问调用https时报错解决办法吧。


PHP 调用CURL提示错误:SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed。这个是因为证书过期导致的。
SSL-ERROR

需要到 http://curl.haxx.se/ca/cacert.pem 下载信任证书。下载后,使其生效有两种方法:

第一种方法:修改 php.ini,找到 [curl]节点,如果没有,可以在php.ini底部添加。


[curl]
;修改为 http://curl.haxx.se/ca/cacert.pem 保存的路径
curl.cainfo="d:/php/cacert.pem"

第二种方法:保存到 程序所在目录,在调用curl的时候,增加一句:


<?php
    
    #cacert.pem 到 http://curl.haxx.se/ca/cacert.pem 下载
    curl_setopt($curl, CURLOPT_CAINFO, dirname(__FILE__) . '/cacert.pem');
?>

 

可以使用下面代码,自动识别https或http

function curlPost($url, $data, $timeout = 30)
 {
     $ssl = substr($url, 0, 8) == "https://" ? TRUE : FALSE;
     $ch = curl_init();
     $opt = array(
             CURLOPT_URL     => $url,
             CURLOPT_POST    => 1,
             CURLOPT_HEADER  => 0,
             CURLOPT_POSTFIELDS      => (array)$data,
             CURLOPT_RETURNTRANSFER  => 1,
             CURLOPT_TIMEOUT         => $timeout,
             );
     if ($ssl)
     {
         $opt[CURLOPT_SSL_VERIFYHOST] = 1;
         $opt[CURLOPT_SSL_VERIFYPEER] = FALSE;
     }
     curl_setopt_array($ch, $opt);
     $data = curl_exec($ch);
     curl_close($ch);
     return $data;
 }
 $data = curlPost('https://www.111cn.net', array('p'=>'hello'));
 echo ($data);
 

PHP检查移动设备只要通过TTP_USER_AGENT就可以进行识别了这样我们只要提前定义好我们目前市面上常用的TTP_USER_AGENT设置即可,下面我们就来看看判断移动设备常用例子吧。

不废话上代码,使用方法就是

 代码如下 复制代码


<?php
if(isMobile()){}
if(!isMobile()){}
 ?>


function isMobile() {

$user_agent = $_SERVER['HTTP_USER_AGENT'];
$mobile_agents = Array("240x320", "acer", "acoon", "acs-", "abacho", "ahong", "airness", "alcatel", "amoi", "android", "anywhereyougo.com", "applewebkit/525", "applewebkit/532", "asus", "audio", "au-mic", "avantogo", "becker", "benq", "bilbo", "bird", "blackberry", "blazer", "bleu", "cdm-", "compal", "coolpad", "danger", "dbtel", "dopod", "elaine", "eric", "etouch", "fly ", "fly_", "fly-", "go.web", "goodaccess", "gradiente", "grundig", "haier", "hedy", "hitachi", "htc", "huawei", "hutchison", "inno", "ipad", "ipaq", "ipod", "jbrowser", "kddi", "kgt", "kwc", "lenovo", "lg ", "lg2", "lg3", "lg4", "lg5", "lg7", "lg8", "lg9", "lg-", "lge-", "lge9", "longcos", "maemo", "mercator", "meridian", "micromax", "midp", "mini", "mitsu", "mmm", "mmp", "mobi", "mot-", "moto", "nec-", "netfront", "newgen", "nexian", "nf-browser", "nintendo", "nitro", "nokia", "nook", "novarra", "obigo", "palm", "panasonic", "pantech", "philips", "phone", "pg-", "playstation", "pocket", "pt-", "qc-", "qtek", "rover", "sagem", "sama", "samu", "sanyo", "samsung", "sch-", "scooter", "sec-", "sendo", "sgh-", "sharp", "siemens", "sie-", "softbank", "sony", "spice", "sprint", "spv", "symbian", "tablet", "talkabout", "tcl-", "teleca", "telit", "tianyu", "tim-", "toshiba", "tsm", "up.browser", "utec", "utstar", "verykool", "virgin", "vk-", "voda", "voxtel", "vx", "wap", "wellco", "wig browser", "wii", "windows ce", "wireless", "xda", "xde", "zte");

$is_mobile = false;
foreach ($mobile_agents as $device) {
  if (stristr($user_agent, $device)) {
    $is_mobile = true;
    break;
  }
}
return $is_mobile;
}

网友补充了一个

 代码如下 复制代码

<?php
function isMobile()
{
    // 如果有HTTP_X_WAP_PROFILE则一定是移动设备
    if (isset ($_SERVER['HTTP_X_WAP_PROFILE']))
    {
        return true;
    }
    // 如果via信息含有wap则一定是移动设备,部分服务商会屏蔽该信息
    if (isset ($_SERVER['HTTP_VIA']))
    {
        // 找不到为flase,否则为true
        return stristr($_SERVER['HTTP_VIA'], "wap") ? true : false;
    }
    // 脑残法,判断手机发送的客户端标志,兼容性有待提高
    if (isset ($_SERVER['HTTP_USER_AGENT']))
    {
        $clientkeywords = array ('nokia',
            'sony',
            'ericsson',
            'mot',
            'samsung',
            'htc',
            'sgh',
            'lg',
            'sharp',
            'sie-',
            'philips',
            'panasonic',
            'alcatel',
            'lenovo',
            'iphone',
            'ipod',
            'blackberry',
            'meizu',
            'android',
            'netfront',
            'symbian',
            'ucweb',
            'windowsce',
            'palm',
            'operamini',
            'operamobi',
            'openwave',
            'nexusone',
            'cldc',
            'midp',
            'wap',
            'mobile'
            );
        // 从HTTP_USER_AGENT中查找手机浏览器的关键字
        if (preg_match("/(" . implode('|', $clientkeywords) . ")/i", strtolower($_SERVER['HTTP_USER_AGENT'])))
        {
            return true;
        }
    }
    // 协议法,因为有可能不准确,放到最后判断
    if (isset ($_SERVER['HTTP_ACCEPT']))
    {
        // 如果只支持wml并且不支持html那一定是移动设备
        // 如果支持wml和html但是wml在html之前则是移动设备
        if ((strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') !== false) && (strpos($_SERVER['HTTP_ACCEPT'], 'text/html') === false || (strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') < strpos($_SERVER['HTTP_ACCEPT'], 'text/html'))))
        {
            return true;
        }
    }
    return false;
}
?>

国外人喜欢写类,有一个Mobile Detect

Mobile_Detect 简单使用实例

 代码如下 复制代码

include 'Mobile_Detect.php';
$detect = new Mobile_Detect();
 
// Check for any mobile device.
if ($detect->isMobile())
 
// Check for any tablet.
if($detect->isTablet())
 
// Check for any mobile device, excluding tablets.
if ($detect->isMobile() && !$detect->isTablet())
 
if ($detect->isMobile() && !$detect->isTablet())
 
// Alternative to $detect->isAndroidOS()
$detect->is('AndroidOS');
 
// Batch usage
foreach($userAgents as $userAgent){
  $detect->setUserAgent($userAgent);
  $isMobile = $detect->isMobile();
}
 
// Version check.
$detect->version('iPad'); // 4.3 (float)

[!--infotagslink--]

相关文章

  • php语言实现redis的客户端

    php语言实现redis的客户端与服务端有一些区别了因为前面介绍过服务端了这里我们来介绍客户端吧,希望文章对各位有帮助。 为了更好的了解redis协议,我们用php来实现...2016-11-25
  • jQuery+jRange实现滑动选取数值范围特效

    有时我们在页面上需要选择数值范围,如购物时选取价格区间,购买主机时自主选取CPU,内存大小配置等,使用直观的滑块条直接选取想要的数值大小即可,无需手动输入数值,操作简单又方便。HTML首先载入jQuery库文件以及jRange相关...2015-03-15
  • 详解如何清理redis集群的所有数据

    这篇文章主要介绍了详解如何清理redis集群的所有数据,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-18
  • Redis连接池配置及初始化实现

    这篇文章主要介绍了Redis连接池配置及初始化实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-29
  • JS实现的简洁纵向滑动菜单(滑动门)效果

    本文实例讲述了JS实现的简洁纵向滑动菜单(滑动门)效果。分享给大家供大家参考,具体如下:这是一款纵向布局的CSS+JavaScript滑动门代码,相当简洁的手法来实现,如果对颜色不满意,你可以试着自己修改CSS代码,这个滑动门将每一...2015-10-21
  • 详解redis desktop manager安装及连接方式

    这篇文章主要介绍了redis desktop manager安装及连接方式,本文图文并茂给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下...2021-01-15
  • 浅谈redis key值内存消耗以及性能影响

    这篇文章主要介绍了浅谈redis key值内存消耗以及性能影响,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-07
  • jQuery+slidereveal实现的面板滑动侧边展出效果

    我们借助一款jQuery插件:slidereveal.js,可以使用它控制面板左右侧滑出与隐藏等效果,项目地址:https://github.com/nnattawat/slideReveal。如何使用首先在页面中加载jquery库文件和slidereveal.js插件。复制代码 代码如...2015-03-15
  • lua读取redis数据的null判断示例代码

    最近在工作中遇到了一个问题,通过查找相关资料才得知原因是因为返回结果的问题,下面这篇文章主要给大家介绍了关于lua读取redis数据的null判断的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下...2020-06-30
  • PHP+jQuery翻板抽奖功能实现

    翻板抽奖的实现流程:前端页面提供6个方块,用数字1-6依次表示6个不同的方块,当抽奖者点击6个方块中的某一块时,方块翻转到背面,显示抽奖中奖信息。看似简单的一个操作过程,却包含着WEB技术的很多知识面,所以本文的读者应该熟...2015-10-21
  • SpringBoot集成Redis实现消息队列的方法

    这篇文章主要介绍了SpringBoot集成Redis实现消息队列的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-10
  • redis setIfAbsent和setnx的区别与使用说明

    这篇文章主要介绍了redis setIfAbsent和setnx的区别与使用,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-08-04
  • SQLMAP结合Meterpreter实现注入渗透返回shell

    sqlmap 是一个自动SQL 射入工具。它是可胜任执行一个广泛的数据库管理系统后端指印, 检索遥远的DBMS 数据库等,下面我们来看一个学习例子。 自己搭建一个PHP+MYSQ...2016-11-25
  • Redis的Expire与Setex区别说明

    这篇文章主要介绍了Redis的Expire与Setex区别说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-15
  • PHP实现今天是星期几的几种写法

    复制代码 代码如下: // 第一种写法 $da = date("w"); if( $da == "1" ){ echo "今天是星期一"; }else if( $da == "2" ){ echo "今天是星期二"; }else if( $da == "3" ){ echo "今天是星期三"; }else if( $da == "4"...2013-10-04
  • 原生js实现fadein 和 fadeout淡入淡出效果

    js里面设置DOM节点透明度的函数属性:filter= "alpha(opacity=" + value+ ")"(兼容ie)和opacity=value/100(兼容FF和GG)。 先来看看设置透明度的兼容性代码: 复制代码 代码如下: function setOpacity(ele, opacity) { if (...2014-06-07
  • 微信小程序(应用号)开发新闻客户端实例

    这篇文章主要介绍了微信小程序(应用号)开发新闻客户端实例的相关资料,需要的朋友可以参考下...2016-10-25
  • 查看Redis内存信息的命令

    Redis 是一个开源、高性能的Key-Value数据库,被广泛应用在服务器各种场景中。本文介绍几个查看Redis内存信息的命令,包括常用的info memory、info keyspace、bigkeys等。...2021-01-15
  • 在页面中输出当前客户端时间javascript实例代码

    这篇文章主要介绍了在页面中输出当前客户端时间javascript实例代码的相关资料,需要的朋友可以参考下...2016-03-03
  • 客户端实现蓝牙接收(C#)知识总结

    网上有关蓝牙接收的资料很多,使用起来也很简单,但是我觉得还是有必要把这些知识总结下来,蓝牙开发需要用到一个第三方的库InTheHand.Net.Personal.dll,感兴趣的朋友可以了解下,或许对你有所帮助...2020-06-25