php源码 阅读器,PHP源码阅读点滴

下面讨论的PHP都是5.1.5版本的。

1. PHP源码文件 Zend/zend_globals.h 中的_zend_executor_globals定义了执行时全局的hash表:

/* symbol table cache */

HashTable *symtable_cache[SYMTABLE_CACHE_SIZE];

HashTable **symtable_cache_limit;

HashTable **symtable_cache_ptr;

HashTable *active_symbol_table;

HashTable symbol_table;     /* main symbol table */

HashTable included_files;   /* files already included */

HashTable *function_table;  /* function symbol table */

HashTable *class_table;     /* class table */

HashTable *zend_constants;  /* constants table */

HashTable *in_autoload;

HashTable regular_list;

HashTable persistent_list;

HashTable *ini_directives;

这里面只列了hash表类型的字段,从中可以看出: 函数、类、常量、头文件等都是存储为hash表的。

2. PHP源码文件 Zend/zend_globals.h 中的下列结构应该说明declare 关键字可以声明的内容都有哪些,似乎目前只有ticks

typedef struct _zend_declarables {

zval ticks;

} zend_declarables;

3. hash表数据结构,Zend/zend_hash.h 文件中:

typedef struct _hashtable {

uint nTableSize;

uint nTableMask;

uint nNumOfElements;

ulong nNextFreeElement;

Bucket *pInternalPointer;   /* Used for element traversal */

Bucket *pListHead;

Bucket *pListTail;

Bucket **arBuckets;

dtor_func_t pDestructor;

zend_bool persistent;

unsigned char nApplyCount;

zend_bool bApplyProtection;

#if ZEND_DEBUG

int inconsistent;

#endif

} HashTable;

4. PHP内部的Hash函数, Zend/zend_hash.h中:

static inline ulong zend_inline_hash_func(char *arKey, uint nKeyLength)

{

register ulong hash = 5381;

/* variant with the hash unrolled eight times */

for (; nKeyLength >= 8; nKeyLength -= 8) {

hash = ((hash << 5) + hash) + *arKey++;

hash = ((hash << 5) + hash) + *arKey++;

hash = ((hash << 5) + hash) + *arKey++;

hash = ((hash << 5) + hash) + *arKey++;

hash = ((hash << 5) + hash) + *arKey++;

hash = ((hash << 5) + hash) + *arKey++;

hash = ((hash << 5) + hash) + *arKey++;

hash = ((hash << 5) + hash) + *arKey++;

}

switch (nKeyLength) {

case 7: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough… */

case 6: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough… */

case 5: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough… */

case 4: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough… */

case 3: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough… */

case 2: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough… */

case 1: hash = ((hash << 5) + hash) + *arKey++; break;

case 0: break;

EMPTY_SWITCH_DEFAULT_CASE()

}

return hash;

}

5. hash表查找函数:

/* Returns SUCCESS if found and FAILURE if not. The pointer to the

* data is returned in pData. The reason is that there’s no reason

* someone using the hash table might not want to have NULL data

*/

ZEND_API int zend_hash_find(HashTable *ht, char *arKey, uint nKeyLength, void **pData)

{

ulong h;

uint nIndex;

Bucket *p;

IS_CONSISTENT(ht);

h = zend_inline_hash_func(arKey, nKeyLength);

nIndex = h & ht->nTableMask;

p = ht->arBuckets[nIndex];

while (p != NULL) {

if ((p->h == h) && (p->nKeyLength == nKeyLength)) {

if (!memcmp(p->arKey, arKey, nKeyLength)) {

*pData = p->pData;

return SUCCESS;

}

}

p = p->pNext;

}

return FAILURE;

}

这里面: h = zend_inline_hash_func(arKey, nKeyLength);

nIndex = h & ht->nTableMask;

就可以定位到具体的Bucket了,特别是这个按位与的操作,就可以知道Bucket的数量了,怎么算呢?

6. 文件Zend/zend_globals_macros.h中定义了EG:

# define EG(v) (executor_globals.v)

EG 就是executor_globals的意思,比如EG(ini_directives) 就是:executor_globals.ini_directives

从上面的结构体executor_globals就可以知道这是在做什么了

7. Zend/zend_ini.h 中定义了ini变量的结构体:

struct _zend_ini_entry {

int module_number;

int modifiable;

char *name;

uint name_length;

ZEND_INI_MH((*on_modify));

void *mh_arg1;

void *mh_arg2;

void *mh_arg3;

char *value;

uint value_length;

char *orig_value;

uint orig_value_length;

int modified;

void (*displayer)(zend_ini_entry *ini_entry, int type);

};

8. ini_set 函数是在源码中是通过函数zend_alter_ini_entry来实现的,其中的modifytype参数值为:PHP_INI_USER

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值