最近问空和isset
函数在php中如何确定变量,刚开始我的脸萌是一种力量,因为我只能依稀,为了了解真实的原则,开放源代码的研究。经过分析,我们可以
发现所有的两个函数调用相同的
功能,所以本文将分析两功能结合在一起。
我有更
详细的注释在GitHub的PHP源代码,你可以看看,给你一颗星星。php5.4源代码注释。你可以看到,已经通过提交记录添加注释。
函数的使用格式
空
清空栈(混合$变量)
确定变量是否为空。
设置 Bool isset(混合为var {,混合$…})
确定变量是否设置,而不是null。
参数描述
空,空只
支持可变参数在php5.5版。其他
类型的参数可能会导致解析
错误,例如,函数调用的结果不能用作参数。
用于设置,如果变量设置为null作为一个功能的设置,该函数返回FALSE。如果多个参数传递给函数的设置,所有的参数都设置了isset函数返回真。从左到右,一旦不设置变量,它停止。
运行实例
$结果空(0);
$结果空(空)
$结果=空(false)
$ =空(数组())
结果=空美元('0'); / /真的
$结果空(1);
$结果=空(回调函数)
$ = null;
结果= isset($ $); / /假;
$ = 1;
结果= isset($ $ / /真实);
$ = 1;$ = 2;$ = 3;
结果= isset(美元$,$,$ C); / /真的
$ = 1;$ = NULL;$ = 3;
结果= isset(美元$,$,$ C); / /假
查找函数定义的
位置。
事实上,空是不是一个函数,但是
语言的结构,语言结构是PHP
程序运行前编译的,所以我们不能简单地寻找php_function空或zend_function空前的源代码。看语言结构如空的源代码,你需要了解PHP代码
执行的机制。
PHP执行代码将经过4个
步骤,流程图如下所示:
在第一阶段,扫描阶段,程序扫描zend_language_scanner。l
文件转换成一个语言片段的代码文件,设置和空函数,在zend_language_scanner空虚时,
搜索,文件可以被定义为宏定义的函数在这个文件如下:
设置{
返回t_isset;
}
空{
返回t_empty;
}
接下来是解析阶段。在这个阶段,程序转换成有意义的表达式t_isset和t_empty令牌。此时,进行语法分析。yacc令牌存储在zend_language_parser。Y文件,和t_isset和t_empty定义可以发现。
internal_functions_in_yacc:
t_isset('' isset_variables){ $ = 3美元;}
|(t_empty '变'(zend_isempty,zend_do_isset_or_isempty){ } $ 3美元,tsrmls_cc);
t_include expr zend_do_include_or_eval(| { } zend_include,2美元美元,tsrmls_cc);
t_include_once expr zend_do_include_or_eval(| { } zend_include_once,2美元美元,tsrmls_cc);
|(t_eval表达式(zend_eval,zend_do_include_or_eval){ } $ 3美元,tsrmls_cc);
t_require expr zend_do_include_or_eval(| { } zend_require,2美元美元,tsrmls_cc);
t_require_once expr zend_do_include_or_eval(| { } zend_require_once,2美元美元,tsrmls_cc);
;
isset和空函数最终执行zend_do_isset_or_isempty功能继续抬头
grep氡zend_do_isset_or_isempty
可以发现,这个功能是在zend_compile定义的C文件。
函数执行的步骤
1。分析参数
2。
检查它是否是一个可写变量。
3、如果变量的op_type是is_cv(编译时变量),设置其
操作码zend_isset_isempty_var;否则,获得下一个
运算值从active_op_array和集last_op码根据其作品的价值。
4、在操作码设置,它将被移交给zend_excute执行。
源代码解释
is_cv是编译器所使用的缓存机制。这个变量保留了它引用的变量的
地址。当第一个变量被引用时,它将被更新。变量的引用将不再需要再次查找活动符号表。
为空函数,操作码的步骤,请参阅操作码
处理功能,可以知道设置空执行在执行时间zend_isset_isempty_var等一系列功能,在zend_isset_isempty_var_spec_cv_var_handler而言,这个函数的定义是在zend_vm_execute.h.the查看功能,发现可以知道空函数的最终执行功能i_zend_is_true(),和i_zend_is_true功能在i_zend_is_true功能zend_execute.h.the
核心代码定义如下:
开关(z_type_p(OP)){
案例is_null:
结果= 0;
打破;
案例is_long:
案例is_bool:
案例is_resource:
0个单词非空参数是一个整数是false。
结果=(z_lval_p(OP)1:0);
打破;
案例is_double:
结果=(z_dval_p(OP)1:0);
打破;
案例is_string:
如果(z_strlen_p(OP)= 0
| |(z_strlen_p(OP)= = 1 z_strval_p(OP){ 0 } = = '0')){
空(0)=真
结果= 0;
{人}
结果= 1;
}
打破;
案例is_array:
根据数组的数目判断空(数组)
结果=(zend_hash_num_elements(z_arrval_p(OP))1:0);
打破;
案例is_object:
如果(is_zend_std_object(* OP)){
tsrmls_fetch();
如果(z_obj_ht_p(OP)-> cast_object){
zval TMP;
如果(z_obj_ht_p(OP)-> cast_object(OP,TMP,is_bool,tsrmls_cc)= =成功){
结果:z_lval(TMP);
打破;
}
} else if(z_obj_ht_p(OP)->得到){
zval * TMP = z_obj_ht_p(OP)->得到(OP tsrmls_cc);
如果(z_type_p(TMP)!= is_object){
为了安全-避免循环。
convert_to_boolean(TMP);
Result = Z_LVAL_P (TMP);
zval_ptr_dtor(TMP);
打破;
}
}
}
结果= 1;
打破;
违约:
结果= 0;
打破;
}
这段代码比较直观,功能不做任何转换的
检测值,通过这个代码进一步分析空函数中的例子做分析:
空(null),is_null结果= 0(i_zend_is_true)分支,i_zend_is_true(0)= =,!= 1,它返回true。
空(假),is_bool分支,结果= zlval_p(假= 0),i_zend_is_true(0)= =,!= = 1(i_zend_is_true),它返回true。
(空)(阵列),结果= zend_hash_num_elements到is_array分支,(z_arrval_p(OP))1:0),zend_hash_num_elements返回数组元素的个数,数组是空的,所以结果是0,i_zend_is_true(0)= =,!= = 1(i_zend_is_true),它返回true。
空('0'),以is_string分支,因为z_strlenp(OP)= 1和z_strval_p(OP){ 0 } = 0,这样的结果是0,i_zend_is_true(0)= =,!= = 1(i_zend_is_true),它返回true。
空(1),对is_long分支,结果= z_lval_p(OP)= 1,i_zend_is_true = 1,i_zend_is_true = 0(!)它返回false。
对于设置功能,最终实现判断代码:
如果z_type_pp(isset(价值)!= is_null){
zval_bool(ex_t(opline ->结果。var)。tmp_var,1);
{人}
zval_bool(ex_t(opline ->结果。var)。tmp_var,0);
}
只要值设置不空,isset函数返回TRUE。
总结
这次读两个函数的源码,
学习了:
编译过程中1,PHP代码的执行步骤
2。如何找到PHP语言结构的源位置
三.如何找到操作码处理功能的具体功能
知识没有极限,每个人都有自己的短板,只有通过不断的学习才能组成自己的短板。
原创文章,写作是有限的,如果没有在这篇论文中有很少的天赋和较少的学习,积极的地方,希望能通知百万。
如果我们帮助你,请
推荐,谢谢^ _ ^
本文深入了解空和设置功能在PHP是萧边共享你的全部内容。我希望能给你一个
参考,希望你能支持它。