为什么要从0.2版本看,因为简单,代码量少
//内核中的MC连接代码
PHP_FUNCTION(memcache_connect)
{ zval **host, **port, **timeout;
注:三个zval结构,分别代码主机地址,端口,超时时间,都是二级指针。
mmc_t *mmc = NULL; //memcache connect point, struct{id,stream,inbuf,timeout}
注:mc连接,mmc_t结构体,包括连接的id,流标识,缓存和超时时间,定义在php_memcache.h中
int timeout_sec = MMC_DEFAULT_TIMEOUT; //default timeout 1 second at current version
注:给超时时间付值,默认是1秒
int ac = ZEND_NUM_ARGS();
注:参数个数,ZEND_NUM_ARGS取参数个数宏,参数可以是2个或者3个,主机地址和端口号必选,超时时间可选
WRONG_PARAM_COUNT;
}
注:接收参数并分别给host,port,timeout付值。如果参数个数不正确(大于3个或小于2个),返回提示错误信息,
注:把主机地址转为字符串类型(其实接收到的就是字符串类型)
convert_to_long_ex(port);
注:把端口号转为long类型(同上,其实就是long)
if (ac == 3) {
convert_to_long_ex(timeout);
timeout_sec = Z_LVAL_PP(timeout);
}
注:如果参数个数等于三,替换默认的超时时间
mmc = mmc_open(Z_STRVAL_PP(host), Z_LVAL_PP(port), timeout_sec);注:打开连接,返回连接指针,mmc_open定义在memcach.c文件中
if (mmc == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't connect to %s:%ld.",Z_STRVAL_PP(host), Z_LVAL_PP(port));
RETURN_FALSE;
}
注:打开失败,返回错误信息
object_init_ex(return_value, memcache_class_entry_ptr);
注:把memcache_class_entry_ptr类初始化一个对象,并把对象的指针给返回值
add_property_resource(return_value, "connection",mmc->id);
注:给返回值加一个属性,名:connection ,值:连接的id(long型)
}
所用到的宏,结构体,和API列表:
zval
php变量在内核中的变量结构体
定义于Zend/zend.h中
struct _zval_struct {
/* Variable information */
zvalue_value value; /* value */
zend_uint refcount__gc;
zend_uchar type; /* active type */
zend_uchar is_ref__gc;
};
mmc_t
定义于php_memcache.h中
typedef struct mmc {
int id;
php_stream *stream;
char inbuf[MMC_BUF_SIZE];
long timeout;
} mmc_t;
MMC_DEFAULT_TIMEOUT
定义于php_memcache.h中
#define MMC_DEFAULT_TIMEOUT 1 /* seconds */
ZEND_NUM_ARGS()
定义于Zend/zend.h中
#define ZEND_NUM_ARGS() (ht)
zend_get_parameters_ex
定义在zend_API.h中
ZEND_API ZEND_ATTRIBUTE_DEPRECATED int zend_get_parameters_ex(int param_count, ...);
ZEND_API宏定义在zend_config.w32.h中,用于声明一个方法是导出还是导入
#ifdef LIBZEND_EXPORTS
# define ZEND_API __declspec(dllexport)
#else
# define ZEND_API __declspec(dllimport)
#endif
没有找到LIBZEND_EXPORTS的声明,所以应该是导入(不确定)
ZEND_ATTRIBUTE_DEPRECATED声明在zend.h中
#if ZEND_GCC_VERSION >= 3001
# define ZEND_ATTRIBUTE_DEPRECATED __attribute__((deprecated))
#elif defined(ZEND_WIN32) && defined(_MSC_VER) && _MSC_VER >= 1300
# define ZEND_ATTRIBUTE_DEPRECATED __declspec(deprecated)
#else
# define ZEND_ATTRIBUTE_DEPRECATED
#endif
根据GCC版本判断的
zend_get_parameters_ex
方法可多于一个参数,第一个参数是个数,后面是要付值的参数指针。
WRONG_PARAM_COUNT
定义于zend_API.h中,相关代码:
#define WRONG_PARAM_COUNT ZEND_WRONG_PARAM_COUNT()
#define ZEND_WRONG_PARAM_COUNT() { zend_wrong_param_count(TSRMLS_C); return; }
zend_wrong_param_count声明于zend_API.h中,实现在zend_API.以中
ZEND_API void zend_wrong_param_count(TSRMLS_D) /* {{{ */
{
const char *space;
const char *class_name = get_active_class_name(&space TSRMLS_CC);
zend_error(E_WARNING, "Wrong parameter count for %s%s%s()", class_name, space, get_active_function_name(TSRMLS_C));
}
如果参数个数不正确,输出一个标准的警告信息,
convert_to_string_ex()
zend_operators.h:#define convert_to_string_ex(ppzv) convert_to_ex_master(ppzv, string, STRING)
zend_operators.h
#define convert_to_ex_master(ppzv, lower_type, upper_type)
if (Z_TYPE_PP(ppzv)!=IS_##upper_type) {
SEPARATE_ZVAL_IF_NOT_REF(ppzv);
convert_to_##lower_type(*ppzv);
}
如果传递的第一个参数的类型不是要转化的类型,则转化。
convert_to_long_ex
zend_operators.h:#define convert_to_log_ex(ppzv) convert_to_ex_master(ppzv, long, LONG)
在zend_operators.h定义了ZEND_API void convert_to_*(zval *op);方法
类似上一个
mmc_opena
定义在memcache.c中static mmc_t* mmc_open(const char *host, short port, long timeout TSRMLS_DC)
分类是主机名,端口,超时时间,TSRMLS_DC根线程安全有关系,具体不详
Z_LVAL_PP
取zval结构值的宏,这里取IS_LONG类型的值,不同类型有不同的宏,定义在zend_operators.h里,后面一个P代码一级指针,两个P代码两级指针。
#define Z_LVAL_PP(zval_pp) Z_LVAL(**zval_pp)
#define Z_LVAL_P(zval_pp) Z_LVAL(*zval_pp)
php_error_docref
输出警告信息
object_init_ex
为某个类初始化一个对象,并把对象的指针返回
add_property_resource
给某个对象增加资源属性,其实增加的资源id