用C写memcache 扩展

jackxiang 2010-9-27 23:40 | |

最新memcache 扩展(教大家开始PHP扩展之旅)
今天花了点时间把扩展又重新写了一遍。去掉了旧的ZEND API 启用了新的API  。而且已经支持了数组和对象等存储。 支持:

mc_connect()  

mc_set()

mc_get()

mc_delete()

mc_flush()

mc_quit()

mc_close()

等基本函数。

先上包包:  mc.tar.gz (508.09 KB)
mc.tar.gz (508.09 KB)
下载次数: 114

2008-5-5 21:30


安装前需要先安装libmemcached 库  ,因为这个扩展是基于最新的libmemcached 库开发的。

代码后面慢慢讲解!!!!!

最后要实现的就是压缩算法。  算法已经选好。  gzlib 算法。 有空了就加上去。

同时在这里谢谢6间房网的toplee大哥对我的指点。忠心感谢。

[ 本帖最后由 逆雪寒 于 2008-5-6 14:33 编辑 ]
本帖最近评分记录
PHPChina 开源币 +10 原创内容 2008-5-28 10:03

学海无崖,回头是岸http://laoniphp.com  

UID
24549
帖子
2335
精华
7
积分
5845
开源币
272  
阅读权限
100
在线时间
1118 小时
注册时间
2007-1-24
最后登录
2008-7-21
查看详细资料

引用 使用道具 报告 回复 TOP

第二周获奖名单公布

逆雪寒

版主



  

个人空间
发短消息
加为好友
当前离线
2# 大 中 小 发表于 2008-5-5 21:31  只看该作者
扩展的环境安装。放到最后再说吧。想讲解代码先

我写扩展的环境是 linux ,  php5.2.5  apache2  ,vim 就这么简单

我们生成扩展环境后。就可以看到mc.c文件。这里主要是我们写扩展的文件。首先我们必须定义我们自己的扩展函数名。需要用PHP_FE() 来定义。如果不定义PHP会认不出我们的函数。

看图。我的这个memcache 扩展。写了几个简单的函数 :

  
1.jpg (24.67 KB)

2008-5-6 09:38



上面定义了  mc_connect()连接mc的函数   mc_set() 把对象或数组或字符等存到memcache 内存的函数。  mc_get() 从memcache 内存获取数值  mc_delete() 干掉内存中我们保存的东西。  mc_flush() 清楚内存中我们保存的数据。 mc_quit() 断开mc连接。   mc_close() 关闭 mc资源


下面我们先讲解第一个函数  mc_connect() 连接函数。这个函数可能是最难的一个了。因为涉及到资源。

  
2.jpg (32.16 KB)

2008-5-6 09:41


我们先自定义一个我们自己的函数。这个还不是PHP意义上的函数。只是我们的一个在C文件里自定义的一个函数。要想成为PHP的函数。那还需要这样:

  
3.jpg (6.94 KB)

2008-5-6 09:42


PHP扩展中。PHP的函数需要用 PHP_FUNCTION  这个宏函数来定义声明。其实所有的逻辑多可以在 PHP_FUNCTION(mc_connect){} 里面实现。但这样做是为了以后更好的扩展。


看 _mc_connect() 这个函数  的   INTERNAL_FUNCTION_PARAMETERS   宏参数。这个参数是PHP 里面给我们定义的宏。因为我们函数 _mc_connect() 需要接受 PHP层 的参数。 但这个函数又不属于PHP 的函数。所以我们需要使用 INTERNAL_FUNCTION_PARAMETERS 宏来创建 PHP函数的环境。
复制PHP内容到剪贴板
PHP代码:
_mc_connect(INTERNAL_FUNCTION_PARAMETERS){  }


继续我们再看一个。PHP扩展中用得最多的东西:
复制PHP内容到剪贴板
PHP代码:
ZEND_NUM_ARGS()


这个宏是用来获取我们输入的参数个数,比如:  xnijiji('s','e')    那么我们的  ZEND_NUM_ARGS() 就会得到2  ,因为这个函数有两个参数。写扩展的时候我们十分需要知道用户输入的参数个数。因为下个接参函数十分需要这个,看:
复制PHP内容到剪贴板
PHP代码:
int zend_parse_parameters(int num_args TSRMLS_DC, char *type_spec, ...);


这个是函数原形。我们看下MC扩展中实际的是这样:
复制PHP内容到剪贴板
PHP代码:
char *hostname;
long port;
int s_len;
int args = ZEND_NUM_ARGS();
zend_parse_parameters(args TSRMLS_CC,"sl", &hostname,&s_len,&port)==FAILURE


我们先用整形变量 args 来获取 参数的个数。  然后使用  zend_parse_parameters() 来接收我们的参数值。  

参数: 字符指针  hostname  是 MC服务器地址  .  s_len 当然是字符长度拉。不废话。  port 很简单是  MC服务器端口拉。
OK。这个讲解完了继续

TSRMLS_CC  这个鸟是在多线程的服务器上。为了线程安全的宏。太高级了。我们不鸟。跳过。  

"sl"   这个又是什么东西呢。    s  代表我们接受的第一个参数是字符形的  l  当表我们接受长整形的。   C语言就是类型很严格。还是PHP爽。那里还管你什么鸟类型。 类型一定要对哦。要不会出现错误。

如果用户输入参数过多。或是类型不对。那么我们就用宏  :

WRONG_PARAM_COUNT;

来发出一个错误。看E文就知道。就是说 参数个数太多了。

如果用户输入参数正确。那么我们就可以 做进一步的处理了。就是拿那些参数的值做我们想做的事。

我们拿什么操作memcache 呢?  我选择了比较新的libmemcached 库。 所以我们也要懂这个库。这个是C语言中操作memcache 的一个库。下面我们来简单的看下这个库
复制PHP内容到剪贴板
PHP代码:
memcached_st *yhm_memc;
memcached_return yhm_rc;


memcached_st 是  libmemcached 库自己定义的数据类型。是接受MC资源或是说句柄或是说字符描述符的。
memcached_return 呢 这个是来接受返回结果的。结果有 MEMCACHED_SUCCESS  等等信息。


看下怎么用。我们用libmemcached 来连接memcache :
复制PHP内容到剪贴板
PHP代码:
yhm_memc = memcached_create(NULL);
yhm_rc = memcached_server_add(yhm_memc,hostname,port);


memcached_create 是初始化 一个句柄。
memcached_server_add  这个才是主菜。大家看就知道了。 它是用来连接mc服务器的。
memcached_server_add(yhm_memc,hostname,port);   hostname  和port 两个变量都是用户输入的。上面有讲解。就这样。  mc在PHP扩展中给连接了。   yhm_memc  这个变量很重要。因为我们连接了MC后。这个变量成了资源。我们在以后的扩展函数中都需要用到。所以存在一个资源保存的问题。


资源怎么保存呢。怎么给每个扩展中的函数使用呢。在注册资源的时候我们需要先在我们这个MC模块启动的时候就注册一个资源注销函数,方便让模块卸载的时候调用清除MC资源

  
6.jpg (36.79 KB)

2008-5-6 10:47



_close_mc_link 函数是我们自定义的  参数:  zend_rsrc_list_entry *rsrc TSRMLS_DC 是一个结构体:里面保存着我们的资源。大概鸟样是这样的:
复制PHP内容到剪贴板
PHP代码:
typedef struct _zend_rsrc_list_entry {
   void *ptr;
   int type;
   int refcount;
} zend_rsrc_list_entry;


成员 void *ptr 才真正指向你的资源。

其实我们不用管那么多。用就是了。
复制PHP内容到剪贴板
PHP代码:
memcached_st *link = (memcached_st *)rsrc->ptr;
memcached_quit(link);


我们使用libmemcached 库的  memcached_quit() 来断开资源连接。逻辑是实现了。但还要注册到PHP内核才行。

注册到内核我们使用:
复制PHP内容到剪贴板
PHP代码:
le_link=zend_register_list_destructors_ex(_close_mc_link,NULL,RESOURCE_TAG,module_number);


le_link  和  RESOURCE_TAG 和  module_number 都是在头文件定义的。那么上菜看下先:

  
4.jpg (13.44 KB)

2008-5-6 11:01


le_link  静态变量就是我们在注册函数析构函数时返回的资源类型句柄。

资源名  宏RESOURCE_TAG   定义为  yhm_mc  也就是这个资源 var_dump() 的名字为yhm_mc : 看下var_dump() 后的显示
复制PHP内容到剪贴板
PHP代码:
resource(2) of type (yhm_mc)


PHP中注册资源的函数是  zend_register_resource()  



因为常用到所以我再一次封装成自己的宏:
复制PHP内容到剪贴板
PHP代码:
#define YHM_REGISTER_RESOURCE(lk) \
{
    zend_register_resource(return_value,lk,le_link);
}


lk  为需要注册的资源。 le_link 是注册构释时候返回的资源。都是需要的。  return_value 是PHP核心定义的。  是一个zval 容器。里面装的就是返回给PHP层面的值。

OK。大家都了解了吧。我们回到  PHP_FUNCTION(mc_connect) 函数里。里面有这么段:
复制PHP内容到剪贴板
PHP代码:
yhm_memc = memcached_create(NULL);

    yhm_rc = memcached_server_add(yhm_memc,hostname,port);
    if(yhm_rc == MEMCACHED_SUCCESS){
        YHM_REGISTER_RESOURCE(yhm_memc);
    }else{
        RETURN_FALSE;
    }


明白了吧。使用自己的宏 YHM_REGISTER_RESOURCE() 把资源  yhm_memc  注册到PHP里面去。不成功就。RETURN_FALSE;   这个是PHP提供给我们返回 false 的一个宏。

OK。粗略讲完了这个函数。 学扩展需要先看一遍扩展的手册。最好这样拉。要不会有点郁闷

来源:http://fyp832008.blog.163.com/blog/static/91439416200810462028349/

作者:jackxiang@向东博客 专注WEB应用 构架之美 --- 构架之美,在于尽态极妍 | 应用之美,在于药到病除
地址:http://jackxiang.com/post/3546/
版权所有。转载时必须以链接形式注明作者和原始出处及本声明!

评论列表
发表评论

昵称

网址

电邮

打开HTML 打开UBB 打开表情 隐藏 记住我 [登入] [注册]