phpast的简单介绍
华为云服务器特价优惠火热进行中! 2核2G2兆仅需 38 元;4核4G3兆仅需 79 元。购买时间越长越优惠!更多配置及优惠价格请咨询客服。
合作流程: |
今天给各位分享phpast的知识,其中也会对进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
微信号:cloud7591如需了解更多,欢迎添加客服微信咨询。
复制微信号
本文目录一览:
PHP的count(数组)和strlen(字符串)的内部实现。
翻了下PHP内核的定义,大概心中也有了答案了
count()和strlen()都是O(1)的时间复杂度
试想一下如果strlen()需要O(N)的复杂度那未免也太慢了,字符串长度起来的话服务器不是要直接挂掉吗
这两个函数都是典型的空间换时间的做法
我们可以先看看zvalue的结构:
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;
zend_ast *ast;
} zvalue_value;
这里用的是一个联合体,当变量类型是string类型的时候附加存储多了一个len的整型变量,显而易见需要取长度直接利用记录值就可以了,自然就是O(1)
对于count()常用的参数类型应该为数组,对于继承Countable的类暂不作讨论
数组实现方式为Hashtable,直接看看他的结构吧
typedef struct _hashtable {
uint nTableSize; // hash Bucket的大小,最小为8,以2x增长。
uint nTableMask; // nTableSize-1 , 索引取值的优化
uint nNumOfElements; // hash Bucket中当前存在的元素个数,count()函数会直接返回此值
ulong nNextFreeElement; // 下一个数字索引的位置
Bucket *pInternalPointer; // 当前遍历的指针(foreach比for快的原因之一)
Bucket *pListHead; // 存储数组头元素指针
Bucket *pListTail; // 存储数组尾元素指针
Bucket **arBuckets; // 存储hash数组
dtor_func_t pDestructor; // 在删除元素时执行的回调函数,用于资源的释放
zend_bool persistent; //指出了Bucket内存分配的方式。如果persisient为TRUE,则使用操作系统本身的内存分配函数为Bucket分配内存,否则使用PHP的内存分配函数。
unsigned char nApplyCount; // 标记当前hash Bucket被递归访问的次数(防止多次递归)
zend_bool bApplyProtection;// 标记当前hash桶允许不允许多次访问,不允许时,最多只能递归3次
#if ZEND_DEBUG
int inconsistent;
#endif
} HashTable;
count直接获取nNumOfElements大小,所以也是O(1)
补充------------------------------------------------
count() 函数的定义在这里
/* {{{ proto int count(mixed var [, int mode])
Count the number of elements in a variable (usually an array) */
PHP_FUNCTION(count)
{
zval *array;
zend_long mode = COUNT_NORMAL;
zend_long cnt;
zval *element;
ZEND_PARSE_PARAMETERS_START(1, 2)
Z_PARAM_ZVAL(array)
Z_PARAM_OPTIONAL
Z_PARAM_LONG(mode)
ZEND_PARSE_PARAMETERS_END();
switch (Z_TYPE_P(array)) {
case IS_NULL:
php_error_docref(NULL, E_WARNING, "Parameter must be an array or an object that implements Countable");
RETURN_LONG(0);
break;
case IS_ARRAY:
if (mode != COUNT_RECURSIVE) {
//类型为数组时调用zend内核函数 zend_array_count()
cnt = zend_array_count(Z_ARRVAL_P(array));
} else {
cnt = php_count_recursive(Z_ARRVAL_P(array));
}
RETURN_LONG(cnt);
break;
case IS_OBJECT: {
zval retval;
/* first, we check if the handler is defined */
if (Z_OBJ_HT_P(array)-count_elements) {
RETVAL_LONG(1);
if (SUCCESS == Z_OBJ_HT(*array)-count_elements(array, Z_LVAL_P(return_value))) {
return;
}
}
/* if not and the object implements Countable we call its count() method */
if (instanceof_function(Z_OBJCE_P(array), zend_ce_countable)) {
zend_call_method_with_0_params(array, NULL, NULL, "count", retval);
if (Z_TYPE(retval) != IS_UNDEF) {
RETVAL_LONG(zval_get_long(retval));
zval_ptr_dtor(retval);
}
return;
}
/* If There's no handler and it doesn't implement Countable then add a warning */
php_error_docref(NULL, E_WARNING, "Parameter must be an array or an object that implements Countable");
RETURN_LONG(1);
break;
}
default:
php_error_docref(NULL, E_WARNING, "Parameter must be an array or an object that implements Countable");
RETURN_LONG(1);
break;
}
}
如果没有特别指定mode参数为 COUNT_RECURSIVE 的话(即作遍历),跳转到 zend 的数组计数函数 zend_array_count()
#define zend_hash_num_elements(ht) \
(ht)-nNumOfElements
...
...
static uint32_t zend_array_recalc_elements(HashTable *ht)
{
zval *val;
uint32_t num = ht-nNumOfElements;
ZEND_HASH_FOREACH_VAL(ht, val) {
if (Z_TYPE_P(val) == IS_INDIRECT) {
if (UNEXPECTED(Z_TYPE_P(Z_INDIRECT_P(val)) == IS_UNDEF)) {
num--;
}
}
} ZEND_HASH_FOREACH_END();
return num;
}
ZEND_API uint32_t zend_array_count(HashTable *ht)
{
uint32_t num;
if (UNEXPECTED(ht-u.v.flags HASH_FLAG_HAS_EMPTY_IND)) {
num = zend_array_recalc_elements(ht);
if (UNEXPECTED(ht-nNumOfElements == num)) {
ht-u.v.flags = ~HASH_FLAG_HAS_EMPTY_IND;
}
} else if (UNEXPECTED(ht == EG(symbol_table))) {
num = zend_array_recalc_elements(ht);
} else {
num = zend_hash_num_elements(ht);
}
return num;
}
IS_REFERENCE:间接 zval 指的就是其真正的值是存储在其他地方的。注意这个 IS_REFERENCE 类型是不同的,间接 zval 是直接指向另外一个 zval 而不是像 zend_reference 结构体一样嵌入 zval。
只有当数组中有 HASH_FLAG_HAS_EMPTY_IND 这个 flag 时(间接zval)才会对数组进行遍历校验,其他情况下都是直接取 数组(hash table) 里面的 nNumOfElements 的值,答案显而易见了,就是O(1)
深入了解php底层需要了解哪些语言
php 底层是C 语言,故如果想研究底层代码需要掌握C言语相关知识。
php 的zend引擎,包括词法分析,语法分析,AST 等需要掌握编译原理的知识。

PHP变量名、变量值、类型
变量名 =》 zval
变量值 =》zend_value
问题:
引用计数
变量传递,变量赋值
变量的基础结构
变量值:zend_value
typedef union _zend_value {
zend_long lval; /* long value */
double dval; /* double value */
zend_refcounted *counted;
zend_string *str;
zend_array *arr;
zend_object *obj;
zend_resource *res;
zend_reference *ref;
zend_ast_ref *ast;
zval *zv;
void *ptr;
zend_class_entry *ce;
zend_function *func;
struct {
uint32_t w1;
uint32_t w2;
} ww;
} zend_value;
变量名:_zval
typedef struct _zval_struct zval;
struct _zval_struct {
zend_value value; /* value */
union {
struct {
ZEND_ENDIAN_LOHI_4(
zend_uchar type, /* active type */
zend_uchar type_flags,
zend_uchar const_flags,
zend_uchar reserved) /* call info for EX(This) */
} v;
uint32_t type_info;
} u1;
union {
uint32_t var_flags;
uint32_t next; /* hash collision chain */
uint32_t cache_slot; /* literal cache slot */
uint32_t lineno; /* line number (for ast nodes) */
uint32_t num_args; /* arguments number for EX(This) */
uint32_t fe_pos; /* foreach position */
uint32_t fe_iter_idx; /* foreach iterator index */
} u2;
};
变量类型【type】
/* regular data types */
#define IS_UNDEF 0
#define IS_NULL 1
#define IS_FALSE 2
#define IS_TRUE 3
#define IS_LONG 4
#define IS_DOUBLE 5
#define IS_STRING 6
#define IS_ARRAY 7
#define IS_OBJECT 8
#define IS_RESOURCE 9
#define IS_REFERENCE 10
/* constant expressions */
#define IS_CONSTANT 11
#define IS_CONSTANT_AST 12
/* fake types */
#define _IS_BOOL 13
#define IS_CALLABLE 14
/* internal types */
#define IS_INDIRECT 15
#define IS_PTR 17
true 和 flase 没有zend_value 结构, 直接通过type来区分,zend_long和double的变量指直接存储在_zend_value中,不需要额外的value指针。
各种后缀名称分别表示什么类型的文件?
文件扩展名:是操作系统用来标志文件格式的一种机制。通常来说,一个扩展名是跟在文件名后面的,由一个分隔符分隔。在一个像“readme.txt”的文件名中,readme是文件名,txt为扩展名,表示这个文件是一个纯文本文件。
[扩展名大全]
.001;002;003... 超星浏览器
.!!!...Netants暂存文件,未下载完成
.a4p .a5p 为AUTHERWARE原始档案,必须安装AUTHERWARE(软体)
.aiff ...Windows Media Player
.ani...动画滑鼠
.ans...记事本
.ape...Monkey s audio;Winamp 2.81以上版本
.arj...压缩文件 ARJ
.asp...IE或者其他网页浏览器
.au ...Windows Media Player
.avi...Media player;金山影霸(如果不能播放请装divx插件)
.bik...bink player;RADGameTools
.bin...daemon tool虚拟光碟机
.bmp...画图(Windows附件)
.box...Lotus Notes
.c Turbo ...C;记事本
.cab...WinRAR;INSTALL SHELD;Winzip
.caj...Cajviewer
.ccd...daemon tool
.cdr...Corel DRAW;freehand
.chm...Windows帮助文件,可以直接打开
.cmb...ComicGURU
.cpp...C++;记事本
.cue...daemon tool
.cur...静态滑鼠
.Dat...不确定的打开方式(多种格式的资料档案都可能)
.db ...SQL资料库文件
.dbf...Foxbase;Dbase;Visual FoxPro
.ddb...Protel 99 se工程制图软件
.dfi...东方光碟机魔术师
.doc...Microsoft Word
.dwg...AutoCAD工程制图软件
.em...loutlook
.fla...Macromedia Flash 6
.gba...game boy advanced的文件,游戏模拟器
.gho...Norton Ghost
.gif...Acdsee;Internet Explorer
.hlp...Windows帮助文件,可以直接打开
.htm...Internet Explorer
.ico...Windows图示,AcdSee
.img...daemon tool;Winimg
.inf;.ini...记事本
.iso...UltraISO;WinISO
.jpg;.jpeg ...Acdsee;Internet Explorer;其他图像浏览软体
.js ...记事本;DreamWeaver
.lrc...记事本
.m3u...Winamp
.mdf...daemon tool;Fantom CD;Alcohol;ms sql server
.mht...Internet Explorer
.mid...Winamp;Windows Media Player及其它播放器
.mov...quick time
.mp3...Winamp;Media player
.mpg;.mpeg... Windows Media Player;金山影霸2003
.nfo...写字板;DAMN.NFO.Viewer.v2.0
.njx...南极星
.nlc...Book Reader for NLC
.nrg...demon tools(ahead nero记录软体的镜像文件)
.ods...Microsoft Outlook
.opt...Microsoft Developer Studio
.out...Turbo C;记事本
.pcb...protel 99 se
.pdf...AdobeReader
.pdg...超星图书浏览器 ssreader
.php;php3;php4...php脚本文件的副档名
.pps...powerpoint
.ppt...Microsoft PowerPonit
.pqi...drive image
.prc...prc editor3.1
.prj...3D Studio(DOS)
.prz...Freelance Mobile Screen Show Player
.ps ...GSVIEW
.psd...Adobe Photoshop
.qt... Quick time
.r01,r02....WinRAR(打开其中一个其他的会自动解压缩)
.rar...WinRAR
.RAW...media player;金山影霸
.rm;.ram;.ra...RealOne Player
.rmvb;.ra...最新的realone player(61上有)
.rpm...Linux安装程式
.sch...Protel 99 se
.scr...Windows萤幕保护,此环境下可执行文件
.sfv...quicksfv;sfv32w
.srt...Vobsub
.swf...Flash player
.tgz...Winzip
.ti...facdsee
.tiff...Windows映象文件
.tmp...暂存文件,可以删除
.ttf...Open Type
.txt...记事本
.ur...lInternet Explorer
.vcd...daemon tool
.vip...维普浏览器
.vsd...Visio
.wav...Windows Media Player
.wdl...DynaDoc Reader v4.25S中文版
.wpd...Word;frontpage;Quick Viewer
.xls...Microsoft Excel
.zip...Winzip;WinRAR
补充..
*.cda 用cd播放软体
*.ceb 用方正公司Apabi Reader
*.DCP 用DcpReader
*.dxf,dwg 用AutoCAD
*.ets 用非常好印
*.GB 用ReadBook或电子小说阅读器
*.gdb 用Interbase Database
*.gs GSView
*.html,htm,asp mht,asp,php 用ie
*.bin, iso,cue,vcd, ccd, img 用winiso浏览,deamon运行,用刻录软体刻录
*.mp123,au,aiff等等 用winamp
*.mpeg,avi,wmv,wma,mpa,asf 用windows media player9.0
*.srm 用电子书库
*.vdx,vsd 用visio
*.wps 用金山wps
*.wdl 用华康浏览器
关于phpast和的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。
