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

来源:互联网 发布:自动离职算工龄 知乎 编辑:程序博客网 时间:2024/06/08 04:26
PHP_FUNCTION(memcache_add)
{
    php_mmc_store(INTERNAL_FUNCTION_PARAM_PASSTHRU,"add");
}

PHP_FUNCTION(memcache_set)
{
    php_mmc_store(INTERNAL_FUNCTION_PARAM_PASSTHRU,"set");

}

PHP_FUNCTION(memcache_replace)
{
    php_mmc_store(INTERNAL_FUNCTION_PARAM_PASSTHRU,"replace");
}

由上面代码可以看到add 和set,replace实际上走的同一个方法,用参数控制了下。我们接下来看php_mmc_store方法:

代码稍长…………

INTERNAL_FUNCTION_PARAMETERS宏定义如下:

#define INTERNAL_FUNCTION_PARAM_PASSTHRU ht, return_value, return_value_ptr, this_ptr, return_value_used TSRMLS_CC

static void php_mmc_store (INTERNAL_FUNCTION_PARAMETERS, char *command)
{
    zval *id, **key, **var, **expire;

 注:四个zval变量,分别代表在mc中存储的一条数据的id, key, value,过期时间
    mmc_t *mmc;

 注:MC连接对象

    int inx, flags, real_expire, data_len;
    char *data, *real_key;
    int ac = ZEND_NUM_ARGS();
 注:ac=参数个数
    php_serialize_data_t var_hash;
    smart_str buf = {0};
 
    if ((id = getThis()) != 0) {  //如果是对象调用
        if ((inx = mmc_get_connection(id, &mmc TSRMLS_CC)) == 0) {
            RETURN_FALSE;
        }

  注:取连接id
        if (ac < 2 || ac > 3 || zend_get_parameters_ex(ac, &key, &var, &expire) == FAILURE) {
            WRONG_PARAM_COUNT;
        }
       注:如果参数个数少于两个或者多于三个,返回参数个数错误信息

    传递参数给key(键),var(值),expire(过期时间)付值
        convert_to_string_ex(key);
       注:把key转换为字符串
        if (Z_STRLEN_PP(key) > MMC_KEY_MAX_SIZE) {
            real_key = estrndup(Z_STRVAL_PP(key), MMC_KEY_MAX_SIZE);
        }
        else {
            real_key = estrdup(Z_STRVAL_PP(key));
        }
        注:如果key长度大于250个字符,截断取前250个字符作key,小于250个字符,直接作key
        /* default flags & expire */
        flags = 0;
        real_expire = 0;

        if (ac > 2) {
            convert_to_long_ex(expire);
            real_expire = Z_LVAL_PP(expire);
        }
        注:如果是三个参数(传了过期时间),则使用用户传递的过期时间,否则使用默认值0
        switch (Z_TYPE_PP(var)) {
            case IS_STRING:
            case IS_LONG:
            case IS_DOUBLE:

   注:字符串,整形和浮点型的value不进行处理
            case IS_BOOL:
                convert_to_string_ex(var);
                data = Z_STRVAL_PP(var);
                data_len = Z_STRLEN_PP(var);
                break;

   注:布尔型值转为字符串,
            default:
                PHP_VAR_SERIALIZE_INIT(var_hash);
                php_var_serialize(&buf, var, &var_hash TSRMLS_CC);
                PHP_VAR_SERIALIZE_DESTROY(var_hash);
              注:没找到相关资料,猜测下吧,先初始化一个  php_serialize_data_t对象,利用初始化的对象,把var值序列化到buf中,然后注销php_serialize_data_t对象

   注:

   typedef struct {
                char *c;  //字符串
                size_t len; //字符串实际长度
                size_t a;      //给字符串分配空间,128倍数
    } smart_str;

   关于smart_str结构的讲解,参考http://www.phppan.com/2009/10/php-smart_str/
                if (!buf.c) {
                    /* you're trying to save null or smthing went really wrong */
                    RETURN_FALSE;
                }
           注:如果序列化后无值,返回false    
                flags |= MMC_SERIALIZED;

                data = buf.c;
                data_len = buf.len;
                break;
        }

        if (mmc_exec_storage_cmd(mmc, command, real_key, flags, real_expire, data, data_len) > 0) {
            efree(real_key);
            RETURN_TRUE;
        }

       注:调用服务器端存储命令,存储数据到MC中
        efree(real_key);
       注:不管操作是否成功都要释放key站的资源
        RETURN_FALSE;
    }
    
    php_error_docref(NULL TSRMLS_CC, E_NOTICE, "memcache_%s() should not be called like this. Use $memcache->%s() to %s item", command, command, command);
    RETURN_FALSE;
}

原创粉丝点击