PHP实现源代码学习笔记

最近弄了一下PHP实现的源代码,先从CLI(Command Line Interface,非MS的Common Language Interface哦)入手的。笔记有点零散,不过从这些关键字搜索源代码,然后看看上下文也是有好处的。

zend_object_handle

/* {{{ proto DateTime::__construct([string time[, DateTimeZone object]])

   Creates new DateTime object

*/

PHP_METHOD(DateTime, __construct)

zend_parse_parameters//分析参数

ZEND_NUM_ARGS()是传入的参数个数

zend_get_parameters_ex应该是获得参数的方法

//填入 return_value 即可成为函数返回值

STD_PHP_INI_ENTRY("date.timezone", "", PHP_INI_ALL, OnUpdateString, default_timezone, zend_date_globals, date_globals)不知道用来做什么的。

搜了好一阵子,

STD_PHP_INI_ENTRY("mysqli.default_port","3306", PHP_INI_ALL,OnUpdateLong,default_port,zend_mysqli_globals,mysqli_globals)

STD_PHP_INI_ENTRY("mysqli.default_socket",NULL,PHP_INI_ALL,OnUpdateStringUnempty,default_socket,zend_mysqli_globals,mysqli_globals)

好像是配置可以指定的全局变量

date的object的定义

struct _php_date_obj {

 zend_object   std;

 timelib_time *time;

};

应该是一种overlap的对象定义方法,看到

#define INIT_CLASS_ENTRY(class_container, class_name, functions) INIT_OVERLOADED_CLASS_ENTRY(class_container, class_name, functions, NULL, NULL, NULL)

更坚定了这个看法

PHP_GINIT_FUNCTION又不知道用来做什么的,想删掉、设为空,可是好像是初始化的,不能删

PHP_GINIT(date),            /* globals ctor */不知道ctor是什么意思,还有一个dtor也无从下手

//不过看到代码

static PHP_GINIT_FUNCTION(date)

{

 date_globals->default_timezone = NULL;

 date_globals->timezone = NULL;

}

是给全局配置变量用的,以后再说吧。

这里是定义类里的静态常数的

#define REGISTER_DATE_CLASS_CONST_STRING(const_name, value) \

 zend_declare_class_constant_stringl(date_ce_date, const_name, sizeof(const_name)-1, value, sizeof(value)-1 TSRMLS_CC);

 REGISTER_DATE_CLASS_CONST_STRING("ATOM",    DATE_FORMAT_RFC3339);

PHP模型

typedef union _zvalue_value {

 long lval;     /* long value */

 double dval;    /* double value */

 struct {

  char *val;

  int len;

 } str;

 HashTable *ht;    /* hash table value */

 zend_object_value obj;

} zvalue_value;

struct _zval_struct {

 /* Variable information */

 zvalue_value value;  /* value */

 zend_uint refcount;

 zend_uchar type; /* active type */

 zend_uchar is_ref;

};

cfg_get_long获得配置变量

object_init(return_value);初始化返回值

add_property_string(return_value, "name",result->fields[field_offset].name, 1);给返回值赋予属性

RETURN_ZVAL((zval *)data->php_value,1,0);生成zval的返回值

cli_sapi_module是命令行模块

参考php_reflection.c可以获得更多调用信息,参考com_dotnet可以更加了解php externtion的工作原理。

ZEND_METHOD(reflection_function, __construct)中zend_hash_find可以发现函数

如何hold住输出?

php_cli.c中的sapi_cli_ub_write可以hold输出

php_execute_simple_script应该可以简单执行,即不需要<?php ... ?>,后来证实并非如此,还是需要<?php ... ?>,不知道与zend_execute_scripts有什么区别。也没有文档说明一下,真是郁闷,难道源代码只是花瓶摆设?

登记变量

zend_declare_property_string

php_register_variable_ex

symtable1 = Z_ARRVAL_P(track_vars_array);

zend_get_parameters_array_ex获 得参数数组,从com_handlers.c中的static int com_call_method(char *method,  INTERNAL_FUNCTION_PARAMETERS)可以参照用法,可以参照 PHPAPI void php_com_variant_from_zval(VARIANT *v, zval *z, int codepage TSRMLS_DC) 的翻译不同系统的值的方法。反之则用PHPAPI int php_com_zval_from_variant(zval *z,  VARIANT *v, int codepage TSRMLS_DC)。

PHP类型

/* data types */

/* All data types <= IS_BOOL have their constructor/destructors skipped */

#define IS_NULL  0

#define IS_LONG  1

#define IS_DOUBLE 2

#define IS_BOOL  3

#define IS_ARRAY 4

#define IS_OBJECT 5

#define IS_STRING 6

#define IS_RESOURCE 7

#define IS_CONSTANT 8

#define IS_CONSTANT_ARRAY 9

ZVAL_ADDREF增加引用,让系统不要在调用函数完毕后删除

zend_hash_internal_pointer_reset_ex重置循环

zend_hash_get_current_key_ex(Z_OBJPROP_P(z),...获得属性

zend_hash_move_forward_ex(Z_OBJPROP_P(z), &pos);循环下一个

zend_hash_get_current_key_ex(Z_OBJCE_P(z),...获得函数

这样以来就可以轮训所有的函数和属性了。

Main函数中的file_handle.handle.stream.reader是php代码输入,可以改造成流,默认的是文件,只要file_handle.handle.stream.reader=你的输入函数;即可。

另外一个值得一提的是,tsrm_ls

(它有多种define,TSRMLS_D,TSRMLS_DC,TSRMLS_C,TSRMLS_CC)

,这个变量贯穿几乎所有角落,它的创建只是轻描淡写tsrm_ls = ts_resource(0);不过,他是线程安全(Thread Security)的结构所在,还是一个难以理解的void ***,三重指针!


研究下来,Debuger指日可待也。

好啦,希望这些碎片对于完全不了解的人来说有点帮助吧。



 

你可能感兴趣的:(学习笔记)