Recently asked to PHP empty and isset function how to judge the variable, just at the beginning I was a face, because I was only a smattering of knowledge, in order to understand its true principle, hurriedly turn over the source research research. Analysis shows that two functions call the same function, so this article will analyze the two functions together.
I have a more detailed annotation of PHP source code in GitHub. Interested can be onlookers, to a star. PHP5.4 source annotation. You can view the annotations that you have added through a commit record.
Functions using formatting
Empty
Determines whether the variable is empty.
Isset
BOOL Isset (mixed $var [, mixed $ ...])
Determines whether a 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 can cause parsing errors, such as the result of a function call that cannot be a parameter.
For Isset, the function returns False if the variable is set to NULL by a function such as unset. If multiple parameters are passed to the Isset function, then only all parameters are set Isset function returns True. Calculates from left to right, and stops once it encounters a variable that has not been set.
Running the sample
$result = Empty (0); True
$result = empty (null);/true
$result = Empty (false);//true
$result = Empty (Array ());//True
$ result = Empty (' 0 '); True
$result = empty (1);//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
Find where the function is defined
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 code as before. To see empty and other language structure source code, first to understand the PHP code execution mechanism.
The PHP execution code passes through 4 steps, and its flowchart looks like this:
In the first phase, the scanning phase, the program scans the ZEND_LANGUAGE_SCANNER.L file to convert the code file into a language fragment. For the isset and empty functions, searching for empty and isset in the Zend_language_scanner.l file can get the macro definition of the function in this file as follows:
<ST_IN_SCRIPTING> "Isset" {return
t_isset;
}
<ST_IN_SCRIPTING> "Empty" {return
t_empty;
}
Next to the parsing phase, this stage, the program will t_isset and t_empty tokens into meaningful expressions, this time will do parsing, tokens YACC save in Zend_language_ PARSER.Y file, you can find the definition of T_isset and T_empty
INTERNAL_FUNCTIONS_IN_YACC:
t_isset ' (' isset_variables ') ' {$$ = $;}
| T_empty ' (' variable ') ' {zend_do_isset_or_isempty (Zend_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 ' (' expr ') ' {zend_do_include_or_eval (Zend_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);
The isset and empty functions eventually perform the Zend_do_isset_or_isempty function and continue to find
Grep-rn "Zend_do_isset_or_isempty"
As you can see, this function is defined in the zend_compile.c file.
function execution Steps
1. Analytic parameters
2. Check whether it is a writable variable
3, if the op_type of the variable is IS_CV (compile-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, set the opcode after, will be handed over to zend_excute execution.
Source Code Interpretation
IS_CV is a cache mechanism used by the compiler, which holds the address of the variable to which it is referenced, and when a variable is first referenced, it is CV, and then the reference to the variable does not need to find an active symbol table.
For the empty function, after the opcode step, see the opcode handler function, you can see that ISSET and empty execute a series of functions Excute Isempty_var_spec_cv_var_handler, for example, finds the definition of this function in Zend_vm_execute.h. The view function can know that the final execution function of the empty function is I_zend_is_true (), while the I_zend_is_true function is defined in zend_execute.h. The core code for the I_zend_is_true function is as follows:
Switch (z_type_p (OP)) {case Is_null:result = 0;
Break
Case Is_long:case is_bool:case Is_resource://Empty parameter is integer when not 0 is false result = (z_lval_p (OP) 1:0);
Break
Case Is_double:result = (z_dval_p (OP)? 1:0);
Break Case Is_string:if (z_strlen_p (OP) = 0 | | (Z_strlen_p (OP) ==1 && z_strval_p (OP) [0]== ' 0])
{//Empty ("0") = = true result = 0;
else {result = 1;
} break;
Case Is_array://Empty (array) is based on the number of arrays to determine the result = (Zend_hash_num_elements (z_arrval_p (OP)) 1:0;
Break
Case Is_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 do any conversion of the detection value, through this code to further analyze the example of the empty function to do analysis:
Empty (null), to the 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 return 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, the array is empty, so result is 0,i_zend_is_true () = = 0,!i_zend_is_true () = 1, so returns TRUE.
Empty (' 0 '), to the 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 the Is_long branch, result = z_lval_p (OP) = 1,i_zend_is_true = = 1,!i_zend_is_true () = = 0, so return 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 time read the two functions of the source code, learned:
1, the PHP code in the compilation of the implementation steps
2, how to find the PHP language structure of the source code location
3, how to find the opcode processing function of the specific functions
Life-long learning, everyone has their own short board, only through continuous study to their own short board to fill.
Original articles, writing limited, talents, if there is an incorrect text, million hope to inform.
If this article is helpful to you, please point to recommend it, thank ^_^
The above in-depth understanding of PHP empty and isset function is small to share all the content of everyone, hope to give you a reference, but also hope that we support the cloud habitat community.