Skip to content

Latest commit

 

History

History
158 lines (119 loc) · 4.45 KB

06.md

File metadata and controls

158 lines (119 loc) · 4.45 KB

Global变量

1,创建一个扩展

./ext_skel --extname=global

2,扩展global变量

/*定义global变量*/
ZEND_BEGIN_MODULE_GLOBALS(global)
	long  counter;
	char *name;
	int name_len;
ZEND_END_MODULE_GLOBALS(global)

ZEND_DECLARE_MODULE_GLOBALS(global);//申明变量

GLOBAL_G(name); //获取global变量的值

GLOBAL_G(counter) = 10; //给global变量赋值

3,POST|GET|COOKIE|SERVER|ENV|REQUEST|FILES全局变量

#php-fpm 生成 POST|GET|COOKIE|SERVER|ENV|REQUEST|FILES全局变量的流程
php_cgi_startup() -> php_module_startup() -> php_startup_auto_globals() -> 保存变量到symbol_table符号表

php_cgi_startup()在 fpm/fpm/fpm_main.c中定义
php_module_startup() 在main/main.c中定义
php_startup_auto_globals() 在main/php_variables.h中定义
zend_hash_update(&EG(symbol_table), "_GET", sizeof("_GET") + 1, &vars, sizeof(zval *), NULL);

/* 读取$_SERVER变量 */
static PHP_FUNCTION(print_server_vars) {
	zval **val;
	if (zend_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"), (void **)&val) == SUCCESS) {
    	RETURN_ZVAL(*val, 1, 0);
	}else{
   	 RETURN_FALSE;
	}
}


/* 读取$_SERVER[$name] */

ZEND_BEGIN_ARG_INFO(print_server_var_arginfo, 0)
	ZEND_ARG_INFO(0, "name")
ZEND_END_ARG_INFO()

static PHP_FUNCTION(print_server_var) {
	char *name;
	int name_len;
	zval **val;
	HashTable *ht_vars = NULL;
	HashPosition pos;
	zval **ret_val;

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!", &name, &name_len) == FAILURE) {
	    RETURN_NULL();
	}

	if (zend_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"), (void **)&val) == SUCCESS) {
    	ht_vars = Z_ARRVAL_PP(val);
    	
    	//此处需传入大于name长度+1的值,因为字符串值后面需要'\0'
    	
    	if (zend_hash_find(ht_vars, name, name_len+1, (void **)&ret_val) == SUCCESS) {             	RETURN_STRING(Z_STRVAL_PP(ret_val), 0);
    	}else{
        	RETURN_NULL();
    	}
	}else{
    	RETURN_NULL();
	}
}

4,$GLOBALS变量

/*添加globals变量*/
static PHP_FUNCTION(add_globals_vars) {
	SET_VAR_LONG("_LONG", 10); //添加long变量
	SET_VAR_DOUBLE("_DOUBLE", 20.5); //添加double变量
	SET_VAR_STRING("_STRING", "string"); //添加string变量

	zval *arr;
	MAKE_STD_ZVAL(arr);
	array_init(arr);
	add_assoc_string(arr, "e", "hello", 1);
	ZEND_SET_GLOBAL_VAR("_ARRS", arr); //添加zval变量
}

/*添加globals字符串变量*/

5,相关宏

/* 设置global变量 */
#define ZEND_SET_GLOBAL_VAR(name, var)	 ZEND_SET_SYMBOL(&EG(symbol_table), name, var)

#define ZEND_SET_GLOBAL_VAR_WITH_LENGTH(name, name_length, var, _refcount, _is_ref)
	ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), name, name_length, var, _refcount, _is_ref)


/ *设置string类型的global变量 */	
#define SET_VAR_STRING(n, v) {	{ zval *var;
								ALLOC_ZVAL(var);
								ZVAL_STRING(var, v, 0);
								ZEND_SET_GLOBAL_VAR(n, var);}
						}
						

#define SET_VAR_STRINGL(n, v, l) {	{zval *var;
									ALLOC_ZVAL(var);
									ZVAL_STRINGL(var, v, l, 0);
									ZEND_SET_GLOBAL_VAR(n, var);}
							}
							
/* 设置long类型的global变量 */
#define SET_VAR_LONG(n, v)	{{zval *var;	
							ALLOC_ZVAL(var);
							ZVAL_LONG(var, v);
							ZEND_SET_GLOBAL_VAR(n, var);}
						}
						
/* 设置double类型的global变量 */
#define SET_VAR_DOUBLE(n, v) {{	zval *var;	
								ALLOC_ZVAL(var);
								ZVAL_DOUBLE(var, v);
								ZEND_SET_GLOBAL_VAR(n, var);}
						}
						
#define ZEND_SET_SYMBOL(symtable, name, var){
	char *_name = (name);					
	ZEND_SET_SYMBOL_WITH_LENGTH(symtable, _name, strlen(_name)+1, var, 1, 0);
}


#define ZEND_SET_SYMBOL_WITH_LENGTH(symtable, name, name_length, var, _refcount, _is_ref){
	zval **orig_var;						
	if (zend_hash_find(symtable, (name), (name_length), (void **) &orig_var)==SUCCESS
		&& PZVAL_IS_REF(*orig_var)) {		
		Z_SET_REFCOUNT_P(var, Z_REFCOUNT_PP(orig_var));
		Z_SET_ISREF_P(var);					
		if (_refcount) {					
			Z_SET_REFCOUNT_P(var, Z_REFCOUNT_P(var) + _refcount - 1);
		}									
		zval_dtor(*orig_var);				
		**orig_var = *(var);				
		FREE_ZVAL(var);						
	} else {								
		Z_SET_ISREF_TO_P(var, _is_ref);		
		if (_refcount) {					
			Z_SET_REFCOUNT_P(var, _refcount);
		}									
		zend_hash_update(symtable, (name), (name_length), &(var), sizeof(zval *), NULL);
	}										
}