线程安全宏定义
TSRM/TSRM.h文件中有如下定义
#define TSRMLS_FETCH() void ***tsrm_ls = (void ***) ts_resource_ex(0, NULL)
#define TSRMLS_D void ***tsrm_ls
#define TSRMLS_DC , TSRMLS_D
#define TSRMLS_C tsrm_ls
#define TSRMLS_CC , TSRMLS_C
1.在定义方法时(形参)加上TSRMLS_D 或者TSRMLS_DC(有参数)
2.在调用方法时(实参)用TSRMLS_C或者TSRMLS_CC(有参数)
3 编译报错 error: ‘tsrm_ls’ undeclared (first use in this function) 需要在函数顶部加上TSRMLS_FETCH;
变量相关宏(部分)
SG -> SAPI Global SAPI信息(main/SAPI.h)
EG -> Executor Global 执行时信息(zend/zend_globals_macros.h:43)
PG -> PHP Core Global 主要存储php.ini中的信息 PHP全局变量。php.ini映射一个或者多个PHP全局结构。(main/php_globals.h)
FG -> File Global 文件全局变量。大多数文件I/O或相关的全局变量的数据流都塞进标准扩展出口结构。(ext/standard/file.h)
CG -> Complier Global 编译时信息,包括函数表等(zend_globals_macros.h:32) 用来访问核心全局变量。(zend/zend_globals_macros.h)
文件宏:
getcwd() VCWD_GETCWD()
fopen() VCWD_FOPEN
open() VCWD_OPEN() //用于两个参数的版本
open() VCWD_OPEN_MODE() //用于三个参数的open()版本
creat() VCWD_CREAT()
chdir() VCWD_CHDIR()
getwd() VCWD_GETWD()
realpath() VCWD_REALPATH()
rename() VCWD_RENAME()
stat() VCWD_STAT()
lstat() VCWD_LSTAT()
unlink() VCWD_UNLINK()
mkdir() VCWD_MKDIR()
rmdir() VCWD_RMDIR()
opendir() VCWD_OPENDIR()
popen() VCWD_POPEN()
access() VCWD_ACCESS()
utime() VCWD_UTIME()
chmod() VCWD_CHMOD()
chown() VCWD_CHOWN()
全局变量:
#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();
}
}
包装第三方库:
SEARCH_PATH="/usr/local /usr" #lib搜索的目录
SEARCH_FOR="/include/curl/curl.h" #lib头文件的路径
if test -r $PHP_LIBS/$SEARCH_FOR; then
LIBS_DIR=$PHP_LIBS
else # search default path list
AC_MSG_CHECKING([for libs files in default path])
for i in $SEARCH_PATH ; do
if test -r $i/$SEARCH_FOR; then
LIBS_DIR=$i #搜索到的lib的路径
AC_MSG_RESULT(found in $i)
fi
done
fi
/*验证lib是否存在*/
if test -z "$LIBS_DIR"; then
AC_MSG_RESULT([not found])
AC_MSG_ERROR([Please reinstall the libs distribution])
fi
/*编译的时候添加lib的include目录, -I/usr/include*/
PHP_ADD_INCLUDE($LIBS_DIR/include)
LIBNAME=curl #lib名称
LIBSYMBOL=curl_version #lib的一个函数,用来PHP_CHECK_LIBRARY验证lib
/*验证lib*/
PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL,
[
PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $LIBS_DIR/$PHP_LIBDIR, LIBS_SHARED_LIBADD) #编译的时候链接lib, -llibcurl
AC_DEFINE(HAVE_LIBSLIB,1,[ ])
],[
AC_MSG_ERROR([wrong libs lib version or lib not found])
],[
-L$LIBS_DIR/$PHP_LIBDIR -lm
])
PHP_SUBST(LIBS_SHARED_LIBADD)
遍历数组:
function hello_array_strings($arr) {
if (!is_array($arr)) return NULL;
printf("The array passed contains %d elements ", count($arr));
foreach($arr as $data) {
if (is_string($data)) echo "$data ";
}
}
PHP_FUNCTION(hello_array_strings)
{
zval *arr, **data;
HashTable *arr_hash;
HashPosition pointer;
int array_count;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &arr) == FAILURE) {
RETURN_NULL();
}
arr_hash = Z_ARRVAL_P(arr);
array_count = zend_hash_num_elements(arr_hash);
php_printf("The array passed contains %d elements ", array_count);
for(zend_hash_internal_pointer_reset_ex(arr_hash, &pointer); zend_hash_get_current_data_ex(arr_hash, (void**) &data, &pointer) == SUCCESS; zend_hash_move_forward_ex(arr_hash, &pointer)) {
if (Z_TYPE_PP(data) == IS_STRING) {
PHPWRITE(Z_STRVAL_PP(data), Z_STRLEN_PP(data));
php_printf(" ");
}
}
RETURN_TRUE;
}
输出:
int php_printf(const char *format, ...);
int php_write(void *buf, uint size TSRMLS_DC);
int PHPWRITE(void *buf, uint size);
void php_html_puts(const char *buf, uint size TSRMLS_DC)
//print zval
ZEND_API int zend_print_zval(zval *expr, int indent);
ZEND_API void zend_print_zval_r(zval *expr, int indent TSRMLS_DC);
//sprintf
PHPAPI int spprintf( char **pbuf, size_t max_len, const char *format, ...);
PHPAPI int vspprintf(char **pbuf, size_t max_len, const char *format, va_list ap);
//string strcat
ZEND_API int add_char_to_string(zval *result, const zval *op1, const zval *op2);
ZEND_API int add_string_to_string(zval *result, const zval *op1, const zval *op2);
ZEND_API int concat_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
ZEND_API void zend_str_tolower(char *str, unsigned int length);
ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length);
ZEND_API char *zend_str_tolower_dup(const char *source, unsigned int length);
内存分配:
emalloc(size_t size);
efree(void *ptr);
ecalloc(size_t nmemb, size_t size);
erealloc(void *ptr, size_t size);
estrdup(const char *s);
estrndup(const char *s, unsigned int length);