1
2
3
4
|
CG -> Complier Global 编译时信息,包括函数表等(zend_globals_macros.h:32)
EG -> Executor Global 执行时信息(zend_globals_macros.h:43)
PG -> PHP Core Global 主要存储php.ini中的信息
SG -> SAPI Global SAPI信息
|
1、SG 针对SAPI信息 在main/SAPI.h文件中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
typedef
struct
_sapi_globals_struct {
void
*server_context;
sapi_request_info request_info;
sapi_headers_struct sapi_headers;
int
read_post_bytes;
unsigned
char
headers_sent;
struct
stat global_stat;
char
*default_mimetype;
char
*default_charset;
HashTable *rfc1867_uploaded_files;
long
post_max_size;
int
options;
zend_bool sapi_started;
double
global_request_time;
HashTable known_post_content_types;
zval *callback_func;
zend_fcall_info_cache fci_cache;
zend_bool callback_run;
} sapi_globals_struct;
|
看一下SG的定义
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
BEGIN_EXTERN_C()
#ifdef ZTS
# define SG(v) TSRMG(sapi_globals_id, sapi_globals_struct *, v)
SAPI_API
extern
int
sapi_globals_id;
#else
# define SG(v) (sapi_globals.v)
extern
SAPI_API sapi_globals_struct sapi_globals;
#endif
SAPI_API
void
sapi_startup(sapi_module_struct *sf);
SAPI_API
void
sapi_shutdown(
void
);
SAPI_API
void
sapi_activate(TSRMLS_D);
SAPI_API
void
sapi_deactivate(TSRMLS_D);
SAPI_API
void
sapi_initialize_empty_request(TSRMLS_D);
END_EXTERN_C()
|
成员都在sapi_globals_struct这里了
那么我么可以这样调用
1
2
|
SG(default_mimetype)
SG(request_info).request_uri
|
可以感受一下这么一段代码
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
|
static
int
sapi_cgi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
{
char
buf[SAPI_CGI_MAX_HEADER_LENGTH];
sapi_header_struct *h;
zend_llist_position pos;
long
rfc2616_headers = 0;
if
(SG(request_info).no_headers == 1) {
return
SAPI_HEADER_SENT_SUCCESSFULLY;
}
if
(SG(sapi_headers).http_response_code != 200) {
int
len;
len = sprintf(buf,
"Status: %d\r\n"
, SG(sapi_headers).http_response_code);
PHPWRITE_H(buf, len);
}
if
(SG(sapi_headers).send_default_content_type) {
char
*hd;
hd = sapi_get_default_content_type(TSRMLS_C);
PHPWRITE_H(
"Content-type:"
,
sizeof
(
"Content-type: "
)-1);
PHPWRITE_H(hd, strlen(hd));
PHPWRITE_H(
"\r\n"
, 2);
efree(hd);
}
h = zend_llist_get_first_ex(&sapi_headers->headers, &pos);
while
(h) {
PHPWRITE_H(h->header, h->header_len);
PHPWRITE_H(
"\r\n"
, 2);
h = zend_llist_get_next_ex(&sapi_headers->headers, &pos);
}
PHPWRITE_H(
"\r\n"
, 2);
return
SAPI_HEADER_SENT_SUCCESSFULLY;
}
|
2、EG Executor Globals
EG获取的是struct _zend_execution_globals
结构体中的数据
1
2
3
4
5
6
|
struct
_zend_execution_globals {
...
HashTable symbol_table;
/* 全局作用域,如果没有进入函数内部,全局=活动 */
HashTable *active_symbol_table;
/* 活动作用域,当前作用域 */
...
}
|
通常,使用EG(symbol_table)
获取的是全局作用域中的符号表,使用EG(active_symbol_table)
获取的是当前作用域下的符号表
例如 来定义$foo = 'bar'
1
2
3
4
5
|
zval *fooval;
MAKE_STD_ZVAL(fooval);
ZVAL_STRING(fooval,
"bar"
, 1);
ZEND_SET_SYMBOL(EG(active_symbol_table),
"foo"
, fooval);
|
或者从符号表中查找$foo
1
2
3
4
5
6
|
zval **fooval;
if
(zend_hash_find(&EG(symbol_table),
"foo"
,
sizeof
(
"foo"
), (
void
**)&fooval) == SUCCESS) {
RETURN_STRINGL(Z_STRVAL_PP(fooval), Z_STRLEN_PP(fooval));
}
else
{
RETURN_FALSE;
}
|
上面的代码中,EG(active_symbol_table) == &EG(symbol_table)
3、CG() 用来访问核心全局变量。(zend/zend_globals_macros.h)
4、PG() PHP全局变量。我们知道php.ini会映射一个或者多个PHP全局结构。(main/php_globals.h)
5、FG() 文件全局变量。大多数文件I/O或相关的全局变量的数据流都塞进标准扩展出口结构。(ext/standard/file.h)