7月 262011
 

缘起

PHP连接Memcached一般有两个模块可以使用: libmemcached和memcache;
libmemcached是不支持PHP的长连接的,但是这个模块对各种错误的处理支持的比较好,如果不要求长连接的话,一般使用该模块。
memcache模块自从我开始使用(3年前)用的是2.2.4版本,到现在stable才到2.2.6; 开发极慢,而且最为让人诟病的一个bug就是: get($key)的返回值对于连接失败和NOT FOUND都是返回false的,以至于我无法知道究竟是哪种错误;如果我不关心二者的区别也就算了,对于必须(或者非常有必要)区别二者的话,只好选择使用libmemcached了。

现在遇到的问题是: 我既要区分连接失败和NOT FOUND,我有需要使用长连接,只好去看memcache的源码了。

解决办法

【可直接参看: http://phpor.net/blog/post/888 】

对于memcache的get方法有第二个参数,这个很少使用(而且用的时候也很是不爽的),就是flag参数,该参数为引用传递,旨在回传memcache中的存储标识,而且比较常用的标识就只有几个(如:压缩);看了一下源码,不妨通过该参数来回传失败的类型,如果是NOT FOUND,则可以将该参数设置一个特殊的标识,具体修改代码如下:

==== memcache.c ===

  1. int mmc_exec_retrieval_cmd(mmc_pool_t *pool, const char *key, int key_len, 
  2.         zval **return_value, zval *return_flags TSRMLS_DC) /* {{{ */
  3. {
  4.     mmc_t *mmc;
  5.     char *command, *value; 
  6.         /* not found */
  7.             if (result == 0) { 
  8.                 flags |= 1<<30;
  9.                 ZVAL_FALSE(*return_value);
  10.             }
  11. }

下面是一个测试脚本:

  1. <?php
  2. $m = new Memcache();
  3. $m->addServer(“127.0.0.1”, 11211); // this is available
  4. //$m->addServer(“127.0.0.1”, 11219); //this is unavailable
  5. define(“E_MC_NO_FOUND”, 1<<30); 
  6. $flag=0;  // 这个一定要有值,否则是不会回传$flag的,大概这是一个bug吧
  7. $result = $m->get(“noexists”,$flag);
  8. if($result === false) {
  9.     if ($flag & E_MC_NO_FOUND) {
  10.         echo “not found\n”;
  11.     } else {
  12.         echo “connect error\n”;
  13.     }
  14. }
  15. echo “flag:”.decbin($flag);

遗留问题:
为什么$flag 不设置一个值就不能回传内部的值,究竟源码错在了何处?

 Posted by at 上午 9:50

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

(required)

(required)

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据