memcache扩展(0.2版本)源代码讲解(memcache_get_version)

来源:互联网 发布:明星怎么全身美白 知乎 编辑:程序博客网 时间:2024/06/08 04:11
PHP_FUNCTION(memcache_get_version)
{

    zval *id;

    注:zval结构,用来保存调用该方法的当前对象

    mmc_t *mmc;

 注:memcache连接对象

    int inx;
    char *version;
 注:版本信息字符串

    if ((id = getThis()) != 0) {

  注:只有是对象调用情况下才输出版本信息

       if ((inx = mmc_get_connection(id, &mmc TSRMLS_CC)) == 0) {

  注:只有在当前对象建立连接才继续

            RETURN_FALSE;

        }
        

        if ( (version = mmc_get_version(mmc)) ) {

            RETURN_STRING(version, 1);

   注:在memcache连接对象中获取版本信息

        }

        RETURN_FALSE;

       注:获取不到版本信息返回false

    }
    

    php_error_docref(NULL TSRMLS_CC, E_WARNING, "memcache_get_version() should not be called like this. Use $memcache->getVersion() instead to get server's version");

 注:此行代码一直无效,暂不清楚原因,可能是该api太旧了…………

    RETURN_FALSE;

}

所用到接口,宏,API列表(上一篇文章介绍过的不再重复介绍):

getThis()

   只有在对象调用情况下才有值,返回值是当前对象在内存中的地址,如果当前不是对象调用,返回0

           例如:memcache->memcache_get_version()返回memcache对象在内存中地址 直接调用memcache_get_version()返回0


mmc_get_connection

返回连接对象,参数:id(memcache对象在内存中地址,通过getThis()获取),mmc要付值的连接对象(zval结构,通过索引付值)

static int mmc_get_connection(zval *id, mmc_t **mmc TSRMLS_DC)
{
    zval    **connection;
    int        resource_type;

    if (zend_hash_find(Z_OBJPROP_P(id), "connection", sizeof("connection"), (void **)&connection) == FAILURE) {
        php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot find connection identifier");
        return 0;
    }

   注:在哈希表中根据id查找连接对象,返回值付给coonection变量

    *mmc = (mmc_t *) zend_list_find(Z_LVAL_PP(connection), &resource_type);
    注:根据连接对象返回mmc结构(mmc是自定义的结构,非zval);
    if (!*mmc || resource_type != le_memcache) {
        php_error_docref(NULL TSRMLS_CC, E_WARNING, "connection identifier not found");
        return 0;
    }
    
    return Z_LVAL_PP(connection);

  返回long型连接id值,就是连接对象(一个zval结构)在内存中的地址
}

mmc_get_version(mmc)

从mmc结构中取出版本信息

mmc结构:

typedef struct mmc {
    int                        id;
    php_stream                *stream;
    char                    inbuf[MMC_BUF_SIZE];
    long                    timeout;
} mmc_t;

/* {{{ mmc_get_version() */
static char *mmc_get_version(mmc_t *mmc)
{
    char *version_str;
    int len;
    
    if (mmc_sendcmd(mmc, "version", 7) < 0) {
        return NULL;
    }

    if ((len = mmc_readline(mmc)) < 0) {
        return NULL;
    }

    if (mmc_str_left(mmc->inbuf,"VERSION ", len, 8)) {
        version_str = estrndup(mmc->inbuf + 8, strlen(mmc->inbuf) - 8 - 2);
        return version_str;
    }
    
    mmc_debug("mmc_get_version: data is not valid version string");    
    return NULL;
}

通过连接服务器端,输入version命令取返回值,获取版本信息,在服务器端telnet上mc后输入version命令

返回格式"VERSION 1.4.5"  从服务器取回的数据,放到inbuf中,然后利用estrndup方法,从inbuf+8的位置copy出一个strlen(mmc->inbuf) - 8 - 2长度的字符串(就是1.4.5)

注意:strlen(mmc->inbuf) - 8 - 2 减8是把"VERSION "(有个空格)减掉,-2是因为返回的“VERSION 1.4.5”后有一个换行符,一个字符串结束符。

RETURN_*

是一组返回值的宏

RETURN_FALSE; 返回false

RETURN_STRING(version, 1); 返回version,第二个参数表示是否copy一份version

还有很多类似的控制返回值的宏…………

原创粉丝点击