$_SERVER, $_SESSION 같은 super globals를 가져오기 위한 방법.
소스파일을 하나 더 추가하므로 config.m4 에도 추가된 소스파일을 명시할 것.
config.m4
PHP_ARG_ENABLE(myext, whether to enable myext support,
[ --enable-myext Enable myext support])
if test "$PHP_MYEXT" = "yes"; then
AC_DEFINE(HAVE_MYEXT, 1, [whether you have myext])
PHP_NEW_EXTENSION(myext, myext.c superglobals.c, $ext_shared)
fi
[ --enable-myext Enable myext support])
if test "$PHP_MYEXT" = "yes"; then
AC_DEFINE(HAVE_MYEXT, 1, [whether you have myext])
PHP_NEW_EXTENSION(myext, myext.c superglobals.c, $ext_shared)
fi
php_myext.h
#ifndef PHP_MYEXT_H
#define PHP_MYEXT_H
#define PHP_MYEXT_VERSION "1.0" // 버전
#define PHP_MYEXT_EXTNAME "myext" // 이름
// Thread Safe Resource Manager
#ifdef ZTS
#include "TSRM.h"
#endif
// $_SERVER 반환
PHP_FUNCTION(myext_get_server_vars);
// 모듈엔트리
extern zend_module_entry myext_module_entry;
#define phpext_myext_ptr &myext_module_entry
#endif
#define PHP_MYEXT_H
#define PHP_MYEXT_VERSION "1.0" // 버전
#define PHP_MYEXT_EXTNAME "myext" // 이름
// Thread Safe Resource Manager
#ifdef ZTS
#include "TSRM.h"
#endif
// $_SERVER 반환
PHP_FUNCTION(myext_get_server_vars);
// 모듈엔트리
extern zend_module_entry myext_module_entry;
#define phpext_myext_ptr &myext_module_entry
#endif
myext.c
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php.h"
#include "php_myext.h"
#include "superglobals.c"
// function entry
static function_entry myext_functions[] = {
PHP_FE(myext_get_server_vars, NULL)
{NULL, NULL, NULL}
};
zend_module_entry myext_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
STANDARD_MODULE_HEADER,
#endif
PHP_MYEXT_EXTNAME,
myext_functions, // function_entry
NULL,
NULL,
NULL,
NULL,
NULL,
#if ZEND_MODULE_API_NO >= 20010901
PHP_MYEXT_VERSION,
#endif
STANDARD_MODULE_PROPERTIES
};
#ifdef COMIPLE_DL_MYEXT
ZEND_GET_MODULE(myext)
#endif
// $_SERVER 반환
PHP_FUNCTION(myext_get_server_vars)
{
RETURN_ZVAL(*$_SERVER, 1, 1);
}
#include "config.h"
#endif
#include "php.h"
#include "php_myext.h"
#include "superglobals.c"
// function entry
static function_entry myext_functions[] = {
PHP_FE(myext_get_server_vars, NULL)
{NULL, NULL, NULL}
};
zend_module_entry myext_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
STANDARD_MODULE_HEADER,
#endif
PHP_MYEXT_EXTNAME,
myext_functions, // function_entry
NULL,
NULL,
NULL,
NULL,
NULL,
#if ZEND_MODULE_API_NO >= 20010901
PHP_MYEXT_VERSION,
#endif
STANDARD_MODULE_PROPERTIES
};
#ifdef COMIPLE_DL_MYEXT
ZEND_GET_MODULE(myext)
#endif
// $_SERVER 반환
PHP_FUNCTION(myext_get_server_vars)
{
RETURN_ZVAL(*$_SERVER, 1, 1);
}
superglobals.c
zval **_get_superglobal(char *sg_name TSRMLS_CC)
{
zval **superglobal;
if (zend_hash_find(&EG(symbol_table), sg_name, strlen(sg_name)+1, (void**)&superglobal)==FAILURE) {
zval *d;
MAKE_STD_ZVAL(d);
array_init(d);
if (zend_hash_add(&EG(symbol_table), sg_name, strlen(sg_name)+1, (void*)*d, sizeof(zval*), NULL)==SUCCESS) {
zend_hash_find(&EG(symbol_table), sg_name, strlen(sg_name)+1, (void**)&superglobal);
}
}
return superglobal;
}
// $_SERVER
#define $_SERVER _get_superglobal("_SERVER" TSRMLS_CC)
{
zval **superglobal;
if (zend_hash_find(&EG(symbol_table), sg_name, strlen(sg_name)+1, (void**)&superglobal)==FAILURE) {
zval *d;
MAKE_STD_ZVAL(d);
array_init(d);
if (zend_hash_add(&EG(symbol_table), sg_name, strlen(sg_name)+1, (void*)*d, sizeof(zval*), NULL)==SUCCESS) {
zend_hash_find(&EG(symbol_table), sg_name, strlen(sg_name)+1, (void**)&superglobal);
}
}
return superglobal;
}
// $_SERVER
#define $_SERVER _get_superglobal("_SERVER" TSRMLS_CC)
super globals는 실행전역(ExecuteGlobals)의 symbol_table에 있다.
해당 테이블은 HashTable이며 찾는 방법은 superglobals.c의 _get_superglobal() 함수에 가장 기본적인 형태로 나와있다.
zend_hash_find() 함수를 이용해서 해당 HashTable을 뒤져서 찾아내 반환한다.
(상단 함수에서 못찾으면 배열 하나를 생성해서 해당 HashTable에 추가해주는 로직도 있다.)
상단의 소스대로 작성해서 var_dump(myext_get_server_vars()); 해보면 $_SERVER의 값들이 출력된다.
잘 보면 HashTable을 뒤질 때 이름을 가지고 찾는데, 같ㅇ느 방식으로 이름만 바꿔서 $_SESSION, $_COOKIE도 가져올 수 있다.
만약 $_SERVER['REMOTE_ADDR']을 가져오고 싶다면 zend_hash_find()를 2단계로 수행하면 된다.
먼저, &EG(symbol_table) 에서 $_SERVER를 가져온다.
가져온 값도 역시 HashTable이다.
그러므로 가져온 HashTable에 한 번 더 zend_hash_find()로 'REMOTE_ADDR' 값을 가져오면 최종적으로 $_SERVER['REMOTE_ADDR'] 값을 가져올 수 있다.
'PHP' 카테고리의 다른 글
[PHP] mod_php5 (SAPI for Apache) (0) | 2010.09.14 |
---|---|
[PHP Extension] Call User Function (0) | 2010.09.13 |
[PHP Extension] C++로 제작하기 위한 config.m4 (0) | 2010.09.09 |
[PHP Extension] 클래스 (Class) (0) | 2010.08.06 |
[PHP Extension] lxr.php.net (OpenGrok) (0) | 2010.08.05 |