[PHP source reading]empty and isset functions, Emptyisset
Recently asked about the PHP empty and isset function how to determine the variables, just at the beginning I was a face, because I was just smattering, in order to understand its true principle, hurriedly opened the source research research. The analysis reveals that all two function calls are the same function, so this article will analyze the two functions together.
I have a more detailed comment on the PHP source code on GitHub. Interested can be onlookers, to a star. PHP5.4 source annotation. Comments that have been added can be viewed through a commit record.
function Use format
Empty
BOOL Empty (mixed $var)
Determines whether the variable is empty.
Isset
BOOL Isset (mixed $var [, mixed $ ...]
Determines whether the variable is set and is not NULL.
Parameter description
For empty, before the PHP5.5 version, empty only supports variable arguments, and other types of arguments result in parsing errors, such as the result of a function call that cannot be used as a parameter.
For Isset, if a variable is set to NULL by a function such as unset, the function returns FALSE. If more than one parameter is passed to the Isset function, only the Isset function will return TRUE if all parameters are set. From left to right, once you have encountered a variable that has not been set, stop.
Run the sample
$result Empty // true $result Empty (null// True
$result Empty (false// true$resultempty(array// true $result Empty // true $result Empty // false $result Empty (callback function// Error
$a = null;
$result = Isset ($a); False
$a = 1;
$result = Isset ($a); True
$a = 1; $b = 2; $c = 3;
$result = Isset ($a, $b, $c); True
$a = 1; $b = null; $c = 3;
$result = Isset ($a, $b, $c); False
Locate the defined position of the function
In fact, empty is not a function, but a language structure. The language structure is compiled before the PHP program is run, so you can't simply search for "php_function empty" or "zend_function empty" to see its source as it did before. To see the source of language structure such as empty, first understand the PHP code execution mechanism.
PHP executes the code in 4 steps, and the flowchart is as follows:
" isset " { return t_isset;} " empty " { return t_empty;}
Next to the parsing stage, this stage, the program will T_isset and T_empty and other tokens into meaningful expressions, this time will do the parsing, tokens Yacc saved in Zend_language_ PARSER.Y file, you can find definitions for t_isset and T_empty:
Internal_functions_in_yacc:t_isset'('Isset_variables')'{ $$ = $3; }| T_empty'('Variable')'{Zend_do_isset_or_isempty (Zend_isempty, &$$, &$3tsrmls_cc); }| T_include Expr {zend_do_include_or_eval (zend_include, &$$, &$2tsrmls_cc); }| T_include_once Expr {zend_do_include_or_eval (zend_include_once, &$$, &$2tsrmls_cc); }| T_eval'('Expr')'{Zend_do_include_or_eval (Zend_eval, &$$, &$3tsrmls_cc); }| T_require Expr {zend_do_include_or_eval (Zend_require, &$$, &$2tsrmls_cc); }| T_require_once Expr {zend_do_include_or_eval (zend_require_once, &$$, &$2tsrmls_cc); };
The isset and empty functions eventually execute the Zend_do_isset_or_isempty function, and continue to find
Grep-rn "Zend_do_isset_or_isempty"
It can be found that this function is defined in the zend_compile.c file.
function execution Steps
1. Analytical parameters
2. Check if it is a writable variable
3, if the op_type of the variable is IS_CV (the compiler time variable), then set its opcode to zend_isset_isempty_var; otherwise get the next op value from Active_op_array, set last_ according to its OP value op's opcode.
4, after setting up the opcode, then will be handed over to zend_excute execution.
SOURCE Interpretation
IS_CV is a cache mechanism used by the compiler, which holds the address of the variable it refers to, and when a variable is referenced for the first time, it is CV-the reference to the variable does not need to look up the active symbol table again.
For the empty function, after the steps of opcode, refer to the opcode handler function, you can know that ISSET and empty are executed in Excute by a series of functions such as Zend_isset_isempty_var to Zend_isset_isempty_var_spec_cv_var_handler , for example, finds the definition of this function in zend_vm_execute.h. The view function knows that the final execution function of the empty function is i_zend_is_true (), whereas the I_zend_is_true function is defined in zend_execute.h. The core code of the I_zend_is_true function is as follows:
Switch(Z_type_p (OP)) { CaseIs_null:result=0; Break; CaseIs_long: CaseIs_bool: CaseIs_resource://False if the empty argument is an integer other than 0result = (z_lval_p (OP)?1:0); Break; CaseIs_double:result= (z_dval_p (OP)?1:0); Break; Caseis_string:if(Z_strlen_p (OP) = =0|| (Z_strlen_p (OP) = =1&& z_strval_p (OP) [0]=='0')) { //empty ("0") = = Trueresult =0; } Else{result=1; } Break; CaseIs_array://empty (array) is judged by the number of arraysresult = (Zend_hash_num_elements (z_arrval_p (OP))?1:0); Break; CaseIs_object:if(Is_zend_std_object (*op)) {Tsrmls_fetch (); if(Z_obj_ht_p (OP),cast_object) {Zval tmp; if(Z_obj_ht_p (OP)->cast_object (OP, &tmp, is_bool tsrmls_cc) = =SUCCESS) {Result=Z_lval (TMP); Break; } } Else if(Z_obj_ht_p (OP),Get) {Zval*tmp = z_obj_ht_p (OP),Get(op tsrmls_cc); if(Z_type_p (tmp)! =is_object) { /*For Safety-avoid Loop*/Convert_to_boolean (TMP); Result=z_lval_p (TMP); Zval_ptr_dtor (&tmp); Break; } }} result=1; Break; default: Result=0; Break; }
This code is more intuitive, the function does not make any conversion of the detection value, through this code to further analyze the example of the empty function to do the analysis:
Empty (null), to Is_null Branch, result=0,i_zend_is_true () = = 0,!i_zend_is_true () = = 1, so returns TRUE.
Empty (false), to the Is_bool branch, result = Zlval_p (false) = 0,i_zend_is_true () = = 0,!i_zend_is_true () = = 1, so returns TRUE.
Empty (Array ()), to Is_array branch, result = Zend_hash_num_elements (z_arrval_p (OP))? 1:0), Zend_hash_num_elements returns the number of array elements, array is empty, so result is 0,i_zend_is_true () = = 0,!i_zend_is_true () = = 1, so returns TRUE.
Empty (' 0 '), to Is_string branch, because Z_STRLENP (OP) = = 1 and z_strval_p (OP) [0] = = ' 0 ', so result is 0,i_zend_is_true () = = 0,!i_zend_is_ True () = = 1, so returns TRUE.
Empty (1), to Is_long branch, result = z_lval_p (OP) = 1,i_zend_is_true = = 1,!i_zend_is_true () = = 0, therefore returns false.
For the Isset function, the code that ultimately implements the judgment is:
if (isset && z_type_pp (value) ! = is_null) { zval_bool (&ex_t). Opline->result.var, 1 );} else { Zval_bool (&ex_t (Opline->result.var). Tmp_var, 0);}
Returns true as long as value is set and is not a null,isset function.
Summary
This reading of the two functions of the source code, learning to:
1, the PHP code during the execution of the procedure
2. How to find the source location of PHP language structure
3. How to find the specific function of opcode processing function
Lifelong learning, everyone has their own short board, only through continuous study to make their own short board to fill.
Original article, writing Limited, Caishuxueqian, if there is not in the text, million hope to inform.
If this article is helpful to you, please click on the recommendation, thank you ^_^
Finally Amway again, I have a more detailed comment on the PHP source code in GitHub. Interested can be onlookers, to a star. PHP5.4 source annotation. Comments that have been added can be viewed through a commit record.
Reference articles
OpCode processing function Lookup: http://www.laruence.com/2008/06/18/221.html
Phpopcode in-depth understanding and PHP code execution steps: Http://www.php-internals.com/book/?p=chapt02/02-03-03-from-opcode-to-handler
More source articles, welcome to personal homepage Continue to view: Hoohack
http://www.bkjia.com/PHPjc/1129313.html www.bkjia.com true http://www.bkjia.com/PHPjc/1129313.html techarticle [php source reading]empty and Isset functions, Emptyisset recently was asked about the empty and isset function in PHP How to judge the variables, just at the beginning I was a face confused, because I am just a know half ...