   如何使用PHP源码来操作memcached服务
如果管理员不让我们去加载 memcache.dll 文件,我们可以直接通过源码操作.先关闭扩展.



mem3.php

<?phprequire_once './memcached.php';$mc = new memcached(array('servers' => array('127.0.0.1:11211'),//连接memcache 的 ip 和端口'debug'   => false, //是否debug'compress_threshold' => 10240,  //最大压缩'persistant' => true));//是否是持久连接$mc->add('key2','hello');
//  $mc->replace('key', 'some random string');$val = $mc->get('key2');
echo $val;
//修改
$mc->set('key1','北京');
$val1 = $mc->get('key1');
var_dump($val1);//删除
$mc->delete('key1');
$val2 = $mc->get('key1');
var_dump($val2);

memcached.php 源码

<?php
//
// +---------------------------------------------------------------------------+
// | memcached client, PHP                                                     |
// +---------------------------------------------------------------------------+
// | Copyright (c) 2003 Ryan T. Dean <rtdean@cytherianage.net>                 |
// | All rights reserved.                                                      |
// |                                                                           |
// | Redistribution and use in source and binary forms, with or without        |
// | modification, are permitted provided that the following conditions        |
// | are met:                                                                  |
// |                                                                           |
// | 1. Redistributions of source code must retain the above copyright         |
// |    notice, this list of conditions and the following disclaimer.          |
// | 2. Redistributions in binary form must reproduce the above copyright      |
// |    notice, this list of conditions and the following disclaimer in the    |
// |    documentation and/or other materials provided with the distribution.   |
// |                                                                           |
// | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR      |
// | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
// | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.   |
// | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,          |
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT  |
// | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY     |
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT       |
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF  |
// | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.         |
// +---------------------------------------------------------------------------+
// | Author: Ryan T. Dean <rtdean@cytherianage.net>                            |
// | Heavily influenced by the Perl memcached client by Brad Fitzpatrick.      |
// |   Permission granted by Brad Fitzpatrick for relicense of ported Perl     |
// |   client logic under 2-clause BSD license.                                |
// +---------------------------------------------------------------------------+
//
// $TCAnet$
///*** This is the PHP client for memcached - a distributed memory cache daemon.* More information is available at http://www.danga.com/memcached/** Usage example:** require_once 'memcached.php';* * $mc = new memcached(array(*              'servers' => array('127.0.0.1:10000', *                                 array('192.0.0.1:10010', 2),*                                 '127.0.0.1:10020'),*              'debug'   => false,*              'compress_threshold' => 10240,*              'persistant' => true));** $mc->add('key', array('some', 'array'));* $mc->replace('key', 'some random string');* $val = $mc->get('key');** @author  Ryan T. Dean <rtdean@cytherianage.net>* @package memcached-client* @version 0.1.2*/// {{{ requirements
// }}}// {{{ constants
// {{{ flags/*** Flag: indicates data is serialized*/
define("MEMCACHE_SERIALIZED", 1<<0);/*** Flag: indicates data is compressed*/
define("MEMCACHE_COMPRESSED", 1<<1);// }}}/*** Minimum savings to store data compressed*/
define("COMPRESSION_SAVINGS", 0.20);// }}}// {{{ class memcached
/*** memcached client class implemented using (p)fsockopen()** @author  Ryan T. Dean <rtdean@cytherianage.net>* @package memcached-client*/
class memcached
{// {{{ properties// {{{ public/*** Command statistics** @var     array* @access  public*/var $stats;// }}}// {{{ private/*** Cached Sockets that are connected** @var     array* @access  private*/var $_cache_sock;/*** Current debug status; 0 - none to 9 - profiling** @var     boolean* @access  private*/var $_debug;/*** Dead hosts, assoc array, 'host'=>'unixtime when ok to check again'** @var     array* @access  private*/var $_host_dead;/*** Is compression available?** @var     boolean* @access  private*/var $_have_zlib;/*** Do we want to use compression?** @var     boolean* @access  private*/var $_compress_enable;/*** At how many bytes should we compress?** @var     interger* @access  private*/var $_compress_threshold;/*** Are we using persistant links?** @var     boolean* @access  private*/var $_persistant;/*** If only using one server; contains ip:port to connect to** @var     string* @access  private*/var $_single_sock;/*** Array containing ip:port or array(ip:port, weight)** @var     array* @access  private*/var $_servers;/*** Our bit buckets** @var     array* @access  private*/var $_buckets;/*** Total # of bit buckets we have** @var     interger* @access  private*/var $_bucketcount;/*** # of total servers we have** @var     interger* @access  private*/var $_active;// }}}// }}}// {{{ methods// {{{ public functions// {{{ memcached()/*** Memcache initializer** @param   array    $args    Associative array of settings** @return  mixed* @access  public*/public function __construct ($args){$this->set_servers($args['servers']);$this->_debug = $args['debug'];$this->stats = array();$this->_compress_threshold = $args['compress_threshold'];$this->_persistant = isset($args['persistant']) ? $args['persistant'] : false;$this->_compress_enable = true;$this->_have_zlib = function_exists("gzcompress");$this->_cache_sock = array();$this->_host_dead = array();}// }}}// {{{ add()/*** Adds a key/value to the memcache server if one isn't already set with * that key** @param   string   $key     Key to set with data* @param   mixed    $val     Value to store* @param   interger $exp     (optional) Time to expire data at** @return  boolean* @access  public*/function add ($key, $val, $exp = 0){return $this->_set('add', $key, $val, $exp);}// }}}// {{{ decr()/*** Decriment a value stored on the memcache server** @param   string   $key     Key to decriment* @param   interger $amt     (optional) Amount to decriment** @return  mixed    FALSE on failure, value on success* @access  public*/function decr ($key, $amt=1){return $this->_incrdecr('decr', $key, $amt);}// }}}// {{{ delete()/*** Deletes a key from the server, optionally after $time** @param   string   $key     Key to delete* @param   interger $time    (optional) How long to wait before deleting** @return  boolean  TRUE on success, FALSE on failure* @access  public*/function delete ($key, $time = 0){if (!$this->_active)return false;$sock = $this->get_sock($key);if (!is_resource($sock))return false;$key = is_array($key) ? $key[1] : $key;$this->stats['delete']++;$cmd = "delete $key $time\r\n";if(!fwrite($sock, $cmd, strlen($cmd))){$this->_dead_sock($sock);return false;}$res = trim(fgets($sock));if ($this->_debug)printf("MemCache: delete %s (%s)\n", $key, $res);if ($res == "DELETED")return true;return false;}// }}}// {{{ disconnect_all()/*** Disconnects all connected sockets** @access  public*/function disconnect_all (){foreach ($this->_cache_sock as $sock)fclose($sock);$this->_cache_sock = array();}// }}}// {{{ enable_compress()/*** Enable / Disable compression** @param   boolean  $enable  TRUE to enable, FALSE to disable** @access  public*/function enable_compress ($enable){$this->_compress_enable = $enable;}// }}}// {{{ forget_dead_hosts()/*** Forget about all of the dead hosts** @access  public*/function forget_dead_hosts (){$this->_host_dead = array();}// }}}// {{{ get()/*** Retrieves the value associated with the key from the memcache server** @param  string   $key     Key to retrieve** @return  mixed* @access  public*/function get ($key){if (!$this->_active)return false;$sock = $this->get_sock($key);if (!is_resource($sock))return false;$this->stats['get']++;$cmd = "get $key\r\n";if (!fwrite($sock, $cmd, strlen($cmd))){$this->_dead_sock($sock);return false;}$val = array();$this->_load_items($sock, $val);if ($this->_debug)foreach ($val as $k => $v)printf("MemCache: sock %s got %s => %s\r\n", $sock, $k, $v);return $val[$key];}// }}}// {{{ get_multi()/*** Get multiple keys from the server(s)** @param   array    $keys    Keys to retrieve** @return  array* @access  public*  get('key1')   keys=array('key1','key2');*/function get_multi ($keys){if (!$this->_active)return false;$this->stats['get_multi']++;foreach ($keys as $key){$sock = $this->get_sock($key);if (!is_resource($sock)) continue;$key = is_array($key) ? $key[1] : $key;if (!isset($sock_keys[$sock])){$sock_keys[$sock] = array();$socks[] = $sock;}$sock_keys[$sock][] = $key;}// Send out the requestsforeach ($socks as $sock){$cmd = "get";foreach ($sock_keys[$sock] as $key){$cmd .= " ". $key;}$cmd .= "\r\n";if (fwrite($sock, $cmd, strlen($cmd))){$gather[] = $sock;} else{$this->_dead_sock($sock);}}// Parse responses$val = array();foreach ($gather as $sock){$this->_load_items($sock, $val);}if ($this->_debug)foreach ($val as $k => $v)printf("MemCache: got %s => %s\r\n", $k, $v);return $val;}// }}}// {{{ incr()/*** Increments $key (optionally) by $amt** @param   string   $key     Key to increment* @param   interger $amt     (optional) amount to increment** @return  interger New key value?* @access  public*/function incr ($key, $amt=1){return $this->_incrdecr('incr', $key, $amt);}// }}}// {{{ replace()/*** Overwrites an existing value for key; only works if key is already set** @param   string   $key     Key to set value as* @param   mixed    $value   Value to store* @param   interger $exp     (optional) Experiation time** @return  boolean* @access  public*/function replace ($key, $value, $exp=0){return $this->_set('replace', $key, $value, $exp);}// }}}// {{{ run_command()/*** Passes through $cmd to the memcache server connected by $sock; returns * output as an array (null array if no output)** NOTE: due to a possible bug in how PHP reads while using fgets(), each*       line may not be terminated by a \r\n.  More specifically, my testing*       has shown that, on FreeBSD at least, each line is terminated only*       with a \n.  This is with the PHP flag auto_detect_line_endings set*       to falase (the default).** @param   resource $sock    Socket to send command on* @param   string   $cmd     Command to run** @return  array    Output array* @access  public*/function run_command ($sock, $cmd){if (!is_resource($sock))return array();if (!fwrite($sock, $cmd, strlen($cmd)))return array();while (true){$res = fgets($sock);$ret[] = $res;if (preg_match('/^END/', $res))break;if (strlen($res) == 0)break;}return $ret;}// }}}// {{{ set()/*** Unconditionally sets a key to a given value in the memcache.  Returns true* if set successfully.** @param   string   $key     Key to set value as* @param   mixed    $value   Value to set* @param   interger $exp     (optional) Experiation time** @return  boolean  TRUE on success* @access  public*/function set ($key, $value, $exp=0){return $this->_set('set', $key, $value, $exp);}// }}}// {{{ set_compress_threshold()/*** Sets the compression threshold** @param   interger $thresh  Threshold to compress if larger than** @access  public*/function set_compress_threshold ($thresh){$this->_compress_threshold = $thresh;}// }}}// {{{ set_debug()/*** Sets the debug flag** @param   boolean  $dbg     TRUE for debugging, FALSE otherwise** @access  public** @see     memcahced::memcached*/function set_debug ($dbg){$this->_debug = $dbg;}// }}}// {{{ set_servers()/*** Sets the server list to distribute key gets and puts between** @param   array    $list    Array of servers to connect to** @access  public** @see     memcached::memcached()*/function set_servers ($list){$this->_servers = $list;$this->_active = count($list);$this->_buckets = null;$this->_bucketcount = 0;$this->_single_sock = null;if ($this->_active == 1)$this->_single_sock = $this->_servers[0];}// }}}// }}}// {{{ private methods// {{{ _close_sock()/*** Close the specified socket** @param   string   $sock    Socket to close** @access  private*/function _close_sock ($sock){$host = array_search($sock, $this->_cache_sock);fclose($this->_cache_sock[$host]);unset($this->_cache_sock[$host]);}// }}}// {{{ _connect_sock()/*** Connects $sock to $host, timing out after $timeout** @param   interger $sock    Socket to connect* @param   string   $host    Host:IP to connect to* @param   float    $timeout (optional) Timeout value, defaults to 0.25s** @return  boolean* @access  private*/function _connect_sock (&$sock, $host, $timeout = 0.25){list ($ip, $port) = explode(":", $host);if ($this->_persistant == 1){$sock = @pfsockopen($ip, $port, $errno, $errstr, $timeout);} else{$sock = @fsockopen($ip, $port, $errno, $errstr, $timeout);}if (!$sock)return false;return true;}// }}}// {{{ _dead_sock()/*** Marks a host as dead until 30-40 seconds in the future** @param   string   $sock    Socket to mark as dead** @access  private*/function _dead_sock ($sock){$host = array_search($sock, $this->_cache_sock);list ($ip, $port) = explode(":", $host);$this->_host_dead[$ip] = time() + 30 + intval(rand(0, 10));$this->_host_dead[$host] = $this->_host_dead[$ip];unset($this->_cache_sock[$host]);}// }}}// {{{ get_sock()/*** get_sock** @param   string   $key     Key to retrieve value for;** @return  mixed    resource on success, false on failure* @access  private*/function get_sock ($key){if (!$this->_active)return false;if ($this->_single_sock !== null)return $this->sock_to_host($this->_single_sock);$hv = is_array($key) ? intval($key[0]) : $this->_hashfunc($key);if ($this->_buckets === null){foreach ($this->_servers as $v){if (is_array($v)){for ($i=0; $i<$v[1]; $i++)$bu[] = $v[0];} else{$bu[] = $v;}}$this->_buckets = $bu;$this->_bucketcount = count($bu);}$realkey = is_array($key) ? $key[1] : $key;for ($tries = 0; $tries<20; $tries++){$host = $this->_buckets[$hv % $this->_bucketcount];$sock = $this->sock_to_host($host);if (is_resource($sock))return $sock;$hv += $this->_hashfunc($tries . $realkey);}return false;}// }}}// {{{ _hashfunc()/*** Creates a hash interger based on the $key** @param   string   $key     Key to hash** @return  interger Hash value* @access  private*/function _hashfunc ($key){$hash = 0;for ($i=0; $i<strlen($key); $i++){$hash = $hash*33 + ord($key[$i]);}return $hash;}// }}}// {{{ _incrdecr()/*** Perform increment/decriment on $key** @param   string   $cmd     Command to perform* @param   string   $key     Key to perform it on* @param   interger $amt     Amount to adjust** @return  interger    New value of $key* @access  private*/function _incrdecr ($cmd, $key, $amt=1){if (!$this->_active)return null;$sock = $this->get_sock($key);if (!is_resource($sock))return null;$key = is_array($key) ? $key[1] : $key;$this->stats[$cmd]++;if (!fwrite($sock, "$cmd $key $amt\r\n"))return $this->_dead_sock($sock);stream_set_timeout($sock, 1, 0);$line = fgets($sock);if (!preg_match('/^(\d+)/', $line, $match))return null;return $match[1];}// }}}// {{{ _load_items()/*** Load items into $ret from $sock** @param   resource $sock    Socket to read from* @param   array    $ret     Returned values** @access  private*/function _load_items ($sock, &$ret){while (1){$decl = fgets($sock);if ($decl == "END\r\n"){return true;} elseif (preg_match('/^VALUE (\S+) (\d+) (\d+)\r\n$/', $decl, $match)){list($rkey, $flags, $len) = array($match[1], $match[2], $match[3]);$bneed = $len+2;$offset = 0;while ($bneed > 0){$data = fread($sock, $bneed);$n = strlen($data);if ($n == 0)break;$offset += $n;$bneed -= $n;$ret[$rkey] .= $data;}if ($offset != $len+2){// Something is borked!if ($this->_debug)printf("Something is borked!  key %s expecting %d got %d length\n", $rkey, $len+2, $offset);unset($ret[$rkey]);$this->_close_sock($sock);return false;}$ret[$rkey] = rtrim($ret[$rkey]);if ($this->_have_zlib && $flags & MEMCACHE_COMPRESSED)$ret[$rkey] = gzuncompress($ret[$rkey]);if ($flags & MEMCACHE_SERIALIZED)$ret[$rkey] = unserialize($ret[$rkey]);} else {if ($this->_debug)print("Error parsing memcached response\n");return 0;}}}// }}}// {{{ _set()/*** Performs the requested storage operation to the memcache server** @param   string   $cmd     Command to perform* @param   string   $key     Key to act on* @param   mixed    $val     What we need to store* @param   interger $exp     When it should expire** @return  boolean* @access  private*/function _set ($cmd, $key, $val, $exp){if (!$this->_active)return false;//get_sock就是去获取到memcached服务器连接$sock = $this->get_sock($key);if (!is_resource($sock))return false;$this->stats[$cmd]++;$flags = 0;if (!is_scalar($val)){$val = serialize($val);$flags |= MEMCACHE_SERIALIZED;if ($this->_debug)printf("client: serializing data as it is not scalar\n");}$len = strlen($val);if ($this->_have_zlib && $this->_compress_enable && $this->_compress_threshold && $len >= $this->_compress_threshold){$c_val = gzcompress($val, 9);$c_len = strlen($c_val);if ($c_len < $len*(1 - COMPRESS_SAVINGS)){if ($this->_debug)printf("client: compressing data; was %d bytes is now %d bytes\n", $len, $c_len);$val = $c_val;$len = $c_len;$flags |= MEMCACHE_COMPRESSED;}}if (!fwrite($sock, "$cmd $key $flags $exp $len\r\n$val\r\n"))return $this->_dead_sock($sock);$line = trim(fgets($sock));if ($this->_debug){if ($flags & MEMCACHE_COMPRESSED)$val = 'compressed data';printf("MemCache: %s %s => %s (%s)\n", $cmd, $key, $val, $line);}if ($line == "STORED")return true;return false;}// }}}// {{{ sock_to_host()/*** Returns the socket for the host** @param   string   $host    Host:IP to get socket for** @return  mixed    IO Stream or false* @access  private*/function sock_to_host ($host){if (isset($this->_cache_sock[$host]))return $this->_cache_sock[$host];$now = time();list ($ip, $port) = explode (":", $host);if (isset($this->_host_dead[$host]) && $this->_host_dead[$host] > $now ||isset($this->_host_dead[$ip]) && $this->_host_dead[$ip] > $now)return null;if (!$this->_connect_sock($sock, $host))return $this->_dead_sock($host);// Do not buffer writesstream_set_write_buffer($sock, 0);$this->_cache_sock[$host] = $sock;return $this->_cache_sock[$host];}// }}}// }}}// }}}
}// }}}
?> 

5. 用 PHP 源码操作 memcache(2)相关推荐

  1. 在Windows和Linux上编译gRPC源码操作步骤(C++)

    gRPC最新发布版本为v1.23.0,下面以此版本为例说明在Windows和Linux下编译过程. Windows7/10 vs2103编译gRPC源码操作步骤: 1. 需要本机已安装Git.CMak ...

  2. java 留言板源码,JSP留言板的JSP源码操作实施

    JSP留言板的JSP源码操作实施 很多JSP编程的爱好者都是出于要做网站的目的,那么网站的PR值就很重要网站的PR值全称为PageRank),是google搜索排名算法中的一个组成部分,级别从1到10 ...

  3. [转]php与memcached服务器交互的分布式实现源码分析[memcache版]

    原文链接:http://www.cnblogs.com/luckcs/articles/2619846.html 前段时间,因为一个项目的关系,研究了php通过调用memcache和memcached ...

  4. Ubuntu 14.04上使用CMake编译MXNet源码操作步骤(Python)

    MXNet源码版本号为1.3.0,其它依赖库的版本号可参考:https://blog.csdn.net/fengbingchun/article/details/84997490 . 为了通过编译源码 ...

  5. Windows10上使用VS2017编译MXNet源码操作步骤(C++)

    MXNet是一种开源的深度学习框架,核心代码是由C++实现.MXNet官网推荐使用VS2015或VS2017编译,因为源码中使用了一些C++14的特性,VS2013是不支持的.这里通过VS2017编译 ...

  6. Ubuntu下安装Cppcheck源码操作步骤

    Cppcheck是用在C.C++中对code进行静态检查的工具.它的源码在  https://github.com/danmar/cppcheck .它的License是GPL-3.0. Cppche ...

  7. Ubuntu14.04上编译指定版本的protobuf源码操作步骤

    Google Protobuf的介绍可以参考 http://blog.csdn.net/fengbingchun/article/details/49977903 ,这里介绍在Ubuntu14.04上 ...

  8. java调用caffe_Caffe中master与windows分支差异对比及通过命令提示符编译Caffe源码操作步骤...

    目前GitHub https://github.com/fengbingchun/Caffe_Test  中的caffe还是依赖较老的版本,更新于2015.08.15,commit为09868ac,近 ...

  9. 海思3559A上编译Valgrind源码操作步骤

    注:按照以下步骤可以在海思板子上正常编译valgrind源码并生成valgrind可执行文件,但可能还不能在海思板子上正常使用. 1. 从http://valgrind.org/downloads/? ...

  10. 海思3559A上编译OpenCV4.1.0源码操作步骤

    1. 从https://github.com/opencv/opencv/releases 下载opencv源码opencv-4.1.0.zip并解压缩: 2. 修改最顶层的CMakeLists.tx ...

最新文章

  1. AI会完美的执行我们设定的目标,但这不是一个好消息
  2. rlm sql mysql.so_UBUUTU7.10上安装配置freeradius+mysql+rp-pppoe手记
  3. linux oracle脚本编写,Linux 脚本编写基础(一)--语法
  4. 【求知探新】Unity中ShaderLab内存优化
  5. 响应式Web设计 viewport 移动端页面自适应
  6. span标签的鼠标滑入提示_彻底搞懂拖拽——基于鼠标事件的拖拽以及基于HTML5 API的拖拽...
  7. Arduino M0 的一个坑(2015-12-25)
  8. JavaScript声明变量详解
  9. 在Ubuntu上安装Drone持续集成环境
  10. 存储器和 I/O 端口有哪两种编址方式?简要说明各自特点
  11. php ajax 同时验证 用户名 密码
  12. ElasticSearch(十二):Spring Data ElasticSearch 的使用(二)
  13. 离线安装docker
  14. 适合64位系统的c语言编辑器,wintc 32/64位软件下载
  15. hibernate HQL 使用from (select ……)子查询的方法
  16. 数字音视频知识点汇总(一)
  17. 【SQL管理】-Flyway数据库版本管理利器从入门到入味
  18. 下载b站外挂字幕,用 potplayer 播放视频也能看字幕了
  19. 有利可图网_公布有利可图的辅助项目手册
  20. 记录linux的内网穿透frp操作

热门文章

  1. webuploader横向按钮样式
  2. Qt配置使用VS2010进行开发
  3. R语言实现常用的5种分析方法(主成分+因子+多维标度+判别+聚类
  4. SpringBoot 集成Netty实现UDP Server
  5. Struct1中 Form表单提交的几种方式以及无刷新提交的方式
  6. sqlserver 获取当前操作的数据库名称
  7. 虚拟机下给Ubuntu挂载新硬盘
  8. 68、secureCRT,vim中输入中文
  9. [BuildRelease]Mozilla Build Tools - Autoconf + GNU Make
  10. javascript常用函数集