前面有篇文章(http://phpor.net/blog/post/883/)提到了PHP 的memcache模块的delete方法的问题,并且做了一些修改,但是,那篇文章也提到,那种修改办法也有很大的缺点,这里给出一种比较好一些的方式。
修改memcache_delete函数如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
PHP_FUNCTION(memcache_delete) { mmc_t *mmc; mmc_pool_t *pool; int result = -1, key_len; zval *mmc_object = getThis(); char *key; long time = 0; char key_tmp[MMC_KEY_MAX_SIZE]; unsigned int key_tmp_len; zval *error_flag = NULL; if (mmc_object == NULL) { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Os|lz", &mmc_object, memcache_class_entry_ptr, &key, &ke y_len, &time, &error_flag) == FAILURE) { return; } } else { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz", &key, &key_len, &time, &error_flag) == FAILURE) { return; } } if (error_flag != NULL) { // 如果提供了默认参数,先析构一下,避免所传参数不是整型; // 即使提供的是一个未初始化的参数,error_flag不是NULL,但是,如果提供的是一个未初始化的参数, // 则该函数里面对值的修改是不能回传过去的 zval_dtor(error_flag); } else { // 如果没有提供默认参数,则初始化之,方便下面的行文 ALLOC_INIT_ZVAL(error_flag); } ZVAL_LONG(error_flag, 0); // 初始化为0 if (!mmc_get_pool(mmc_object, &pool TSRMLS_CC) || !pool->num_servers) { ZVAL_LONG(error_flag, 1 << 30); // 如果网络错误,设置为 1<<30 RETURN_FALSE; } if (mmc_prepare_key_ex(key, key_len, key_tmp, &key_tmp_len TSRMLS_CC) != MMC_OK) { ZVAL_LONG(error_flag, 1 << 28); // 如果key错误,设置为 1<<28 RETURN_FALSE; } while (result < 0 && (mmc = mmc_pool_find(pool, key_tmp, key_tmp_len TSRMLS_CC)) != NULL) { if ((result = mmc_delete(mmc, key_tmp, key_tmp_len, time TSRMLS_CC)) < 0) { mmc_server_failure(mmc TSRMLS_CC); } } if (result > 0) { RETURN_TRUE; } elseif(result == 0) { // not found ZVAL_LONG(error_flag, 1 << 29); // 如果没有找到,设置为 1 << 29 RETURN_FALSE; } ZVAL_LONG(error_flag, 1 << 30); // 如果网络错误,设置为 1<<30 RETURN_FALSE; } |
测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
<?php define("E_MC_KEY_PREPARE_ERROR", 1<<28); define("E_MC_NO_FOUND", 1<<29); define("E_MC_CONNECT_ERROR", 1<<30); test_delete(); exit; function test_delete() { $m = new Memcache(); $m->addServer("127.0.0.1", 11211); // this is available $flag = 0; $result = $m->delete("noexists", 0, $flag); check_error("should no found", $flag); $flag = 0; $m->set("exists","I am here",0,600); $result = $m->delete("exists", 0, $flag); check_error("should ok", $flag); $flag = 0; $m = new Memcache(); $m->addServer("127.0.0.1", 11219); // this is unavailable $result = $m->delete("noexists", 0, $flag); check_error("should connect error", $flag); $flag = 0; $result = @$m->delete("", 0, $flag); // test no flag check_error("should key error", $flag); $result = $m->delete("m", 0); // test no flag echo "it can work without flag argument, that's ok\n"; } function check_error($lable, $flag) { echo $lable .":\t"; if ($flag & E_MC_CONNECT_ERROR) { echo "connect error\n"; } if ($flag & E_MC_NO_FOUND) { echo "no found\n"; } if ($flag & E_MC_KEY_PREPARE_ERROR) { echo "Key in unvalidate\n"; } if ($flag == 0) { echo "OK\n"; } } |
输出结果:
should no found: no found
should ok: OK
should connect error: connect error
should key error: Key in unvalidate
it can work without flag argument, that’s ok
====================================================
本次所学:
1. 关于参数的传递,可以直接解析成内部类型,也可以直接使用zval类型
2. 关于引用传参这里做的不太对,且看后面的文章