北京白癜风的权威专家 http://m.39.net/pf/a_4358929.html写在前方:
swoole的呈现让php投入了除了web的其余范围,php7的机能擢升又再次拓宽了php的运用范畴,比方嬉戏范围,但php7为了擢升机能修正了大批的zendapi,看到新版本的zendapi信任众人得第一反响都是,变换太大了!为啥不兼容以前的,依旧那句话都是为了机能擢升,于是基础总共的php扩大都须要做一个分支拨来赞成新版本php,对扩打开采者来讲须要同时保护两套代码,行使扩大的人就须要针对每个php版本编译不同的so文献对比费事,本文将从另一个角度来试验束缚这个问---经过引入一组兼容层函数来只管少修正扩大代码而且一套代码赞成总共php,而且此计划曾经胜利的运用在了swoole和php-cp(pdo和redis代办)项目中,底下将分为几个部份讲详细的完结以及php7中为甚么改为云云
内存和字符串联系1、MAKE_STD_ZVAL
php7的变换很大的即是内存的部份,首先新打算的zval、zend_string、hashtable(ng中也叫zend_array)等数据组织体积很小而且很紧凑,能充足哄骗cpu的cache,其次大批用栈空间取代在堆中请求内存,反响到扩大层面即是去掉了MAKE_STD_ZVAL和ALLOC_INIT_ZVAL等内存请求的宏界说,由于phpng的zendapi都不须要在堆上请求内存而后把地方传给zendapi(固然假如交易的确须要你也也许手动emalloc内存),swoole和php-cp中是何如做的呢?首先,将扩大中总共的MAKE_STD_ZVAL批量替代为SW_MAKE_STD_ZVAL其次,咱们再看SW_MAKE_STD_ZVAL的界说:
#ifPHP_MAJOR_VERSION7#defineSW_MAKE_STD_ZVAL(p)MAKE_STD_ZVAL(p)#else#defineSW_MAKE_STD_ZVAL(p)zval_stack_zval_##p;p=(_stack_zval_##p)//宏打开后即是在栈上界说的zval#endif
也许看到在phpng中SW_MAKE_STD_ZVAL即是在栈上界说了一个zval而后把地方赋值给p,在以前的php版本中即是直接移用MAKE_STD_ZVAL留神:此办法能适应大部份用到MAKE_STD_ZVAL的处所,然而有些光阴(比方:函数内部将MAKE_STD_ZVAL获得的指针做为函数返回值返回了)是弗成的,须要手动emalloc,就如开首说的经过引入一组兼容层函数来只管少修正扩大代码。
2、zval_ptr_dtor
zval_ptr_dtor在以前的php版本中通报参数是指针的指针,phpng中是zval的指针.首先,将扩大中总共的zval_ptr_dtor替代成sw_zval_ptr_dtor(如下都如斯不再赘述)。兼容宏代码如下:
#ifPHP_MAJOR_VERSION7#definesw_zval_ptr_dtorzval_ptr_dtor#else#definesw_zval_ptr_dtor(p)zval_ptr_dtor(*p)//用*职掌把指针的指针变为指针(好绕口)#endif
有人也许会问,在上头说了是经过栈来摹拟malloc内存,那这边的释放内存是不是会段过错?
if(Z_REFCOUNTED_P(zval_ptr)){if(!Z_DELREF_P(zval_ptr)){_zval_dtor_func_for_ptr(Z_COUNTED_P(zval_ptr)ZEND_FILE_LINE_RELAY_CC);}else{GC_ZVAL_CHECK_POSSIBLE_ROOT(zval_ptr);}}
如上,由于phpng中释放内存以前会决断假如不是引用变量典型就跳过不做任何职掌。
3.zval_add_ref
增加引用计数的办法
/p>
#ifPHP_MAJOR_VERSION7#definesw_zval_add_refzval_add_ref#else#definesw_zval_add_ref(p)Z_TRY_ADDREF_P(*p)//phpng会先决断典型而后再加引用#endif4.SW_ZVAL_STRING,SW_ZVAL_STRINGL,RETURN_STRINGL,RETVAL_STRINGL,RETURN_STRING
在以前的php版本中,这一组函数的末了一个参数是是不是须要复制字符串如下:
Z_STRVAL_P(__z)=(duplicate?estrndup(__s,Z_STRLEN_P(__z))
char*)__s);//duplicate即是上述一组函数的末了一个参数
然而在phpng中一直返回zend_string不须要duplicate参数于是兼容宏如下:
#ifPHP_MAJOR_VERSION7#defineSW_ZVAL_STRINGLZVAL_STRINGL#defineSW_ZVAL_STRINGZVAL_STRING#defineSW_RETURN_STRINGLRETURN_STRINGL#defineSW_RETURN_STRINGRETURN_STRING#defineSW_RETVAL_STRINGLRETVAL_STRINGL#else#defineSW_ZVAL_STRINGL(z,s,l,dup)ZVAL_STRINGL(z,s,l)#defineSW_ZVAL_STRING(z,s,dup)ZVAL_STRING(z,s)#defineSW_RETURN_STRINGL(s,l,dup)RETURN_STRINGL(s,l)#defineSW_RETURN_STRING(val,dup)RETURN_STRING(val)#defineSW_RETVAL_STRINGL(s,l,dup)RETVAL_STRINGL(s,l);#endif
也许看到在phpng中即是浅显的忽视了dup参数,须要留神的是,假如你从来的代码中末了一个参数是0而且第一个参数是在堆上请求的须要efree(s)第一个参数来释放内存。
--------------浩繁的分隔线----------------
PHP饭米粒(phpfamily)由一群靠谱的人设立,愿为PHPer带来一些值得细细品尝的精力粮食!
本文由郭新华向php饭米粒(phpfamily)投稿,转载请阐扬向滥觞音信和如下的