A detailed example of a PHP custom function return value

Source: Internet
Author: User
return value of the function

The function in PHP has a return value, and no return returns null

(1) Return statement

From the Zend/zend_language_parser.y file, you can confirm that the Zend_do_return function is called by its generated intermediate code.

void Zend_do_return (znode *expr, int do_end_vparse TSRMLS_DC)/* * {{*/{zend_op *    Opline; int Start_op_number, End_op_number; if (do_end_vparse) {if (CG (active_op_array)->return_reference &&!zend_is_function_or_me            Thod_call (expr)) {Zend_do_end_variable_parse (expr, bp_var_w, 0 TSRMLS_CC);/* Process return reference */} else { Zend_do_end_variable_parse (expr, bp_var_r, 0 TSRMLS_CC);/* Handle General variable return */}} ...//omit, take other intermediate code operation opline-     >opcode = Zend_return;         if (expr) {opline->op1 = *expr; if (do_end_vparse && zend_is_function_or_method_call (expr)) {Opline->extended_value = Zend_returns_        FUNCTION;        }} else {opline->op1.op_type = Is_const;    Init_zval (opline->op1.u.constant); } set_unused (OPLINE->OP2);} /* }}} */

The

Generates an intermediate code of Zend_return. The type of the first operand is the action type of the expression when the return value is an expression that is available, otherwise the type is is_const. This is useful when performing intermediate code functions in subsequent computations. Depending on the operand, the Zend_return intermediate code executes Zend_return_spec_const_handler,zend_return_spec_tmp_handler or ZEND_RETURN_SPEC_TMP_ HANDLER. The execution flow of these three functions is basically similar, including the handling of some errors. Here we take Zend_return_spec_const_handler as an example to illustrate the execution of function return values:

static int Zend_fastcall Zend_return_spec_const_handler (zend_opcode_handler_args) {Zend_op *opline = EX (opline);    Zval *retval_ptr;      Zval **retval_ptr_ptr; if (EG (active_op_array)->return_reference = = Zend_return_ref) {//ǔǔŷsá\ɂƶmļ@ɗáļļif (Is_const = = IS_C Onst | | Is_const = = Is_tmp_var) {/* Not supposed to happen, but we'll allow it */Zend_error (E_notice, "            Only variable references \ Should is returned by reference ");        Goto Return_by_value;  } retval_ptr_ptr = NULL; Ǔǔŕif (Is_const = = Is_var &&!retval_ptr_ptr) {Zend_error_noreturn (E_error, "Cannot retur        n string offsets by reference "); } if (Is_const = = Is_var &&!)                Z_ISREF_PP (retval_ptr_ptr)) {if (Opline->extended_value = = Zend_returns_function && ex_t (Opline->op1.u.var). var.fcall_returned_reference) {} else if (ex_t (Opline->op1.u.var). var.ptr_ptr = = &ex_t (opline->op1.u.var). var.ptr) {if (Is_const = = Is_var && amp;!0) {/* undo the effect of get_zval_ptr_ptr () */Pzval_lock (*RETVAL_PTR_PTR)                ;                } zend_error (E_notice, "only variable references \ Should is returned by reference");            Goto Return_by_value;   }} if (EG (return_value_ptr_ptr)) {//ǔǔŷs separate_zval_to_make_is_ref (retval_ptr_ptr);    IS_REFGCŐĘZ_ADDREF_PP (RETVAL_PTR_PTR);        Refcountgcœďx1 (*eg (return_value_ptr_ptr)) = (*retval_ptr_ptr);         }} else {return_by_value:retval_ptr = &opline->op1.u.constant; if (! EG (return_value_ptr_ptr)) {if (Is_const = = Is_tmp_var) {}} else if (!0) {/* Not a temp V                AR */if (Is_const = = Is_const | | EG (Active_op_array)->return_rEference = = Zend_return_ref | | (Pzval_is_ref (retval_ptr) && z_refcount_p (retval_ptr) > 0))                 {Zval *ret;                Alloc_zval (ret);   Init_pzval_copy (ret, retval_ptr);                ŁͿʍǔǔŕzval_copy_ctor (ret);            *eg (return_value_ptr_ptr) = ret;            } else {*eg (return_value_ptr_ptr) = Retval_ptr;//ħ6ɶŕz_addref_p (RETVAL_PTR);             }} else {Zval *ret;            Alloc_zval (ret);    Init_pzval_copy (ret, retval_ptr);            ŁͿʍǔǔŕ*eg (return_value_ptr_ptr) = ret;   }} return Zend_leave_helper_spec (Zend_opcode_handler_args_passthru); Ǔǔĉșʒ}

The return value of the

function is stored in *eg (RETURN_VALUE_PTR_PTR) when the program executes. The Zend kernel distinguishes between value return and reference return, and on this basis the constants, temporary variables, and other types of variables are treated differently on return. After the return is executed, the Zend kernel clears the variables used inside the function by calling the Zend_leave_helper_spec function. This is one of the reasons why the Zend kernel automatically adds null to the function.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.