PHP implements a strongly typed function return value

Source: Internet
Author: User
In the development process, the return value type of the function should be deterministic, but PHP is a weakly typed language,

So PHP does not have this kind of syntax verification, because of this, caused a lot of pits.

For example, the following code:

<?phpfunction getarticles (...) {$arrData = array (); if ($exp 1) {return $arrData;} else if ($exp 2) {return 1;} Else{return false;}} $arrData =getarticles (...); foreach ($arrData as $record) {//do something.....}?>

The function Getarticles returns different types of values according to different conditions, with bool, int, and arrays, normally such functions are expected to return an array, and then take the array to do some other operation,

Because the function return value type is not fixed, the call is likely to produce a variety of unexpected pits,

So I thought, since it can't be regulated, it's a direct compulsion.

The function/method return value can enforce the type, as shown in figure

Support for four types of coercion type restriction: int, array, bool, object, when the return value does not match the type in the function declaration, throws the warning, originally wanted to throw the error, but thought

Too hard, can only be considered an anomaly, can not be counted wrong, so use warning good.

PHP itself does not support the syntax of the INT function, so to support the first to take care of the syntax parser, about the syntax parser, you can move here >>> view

Details, this is not said,

Modify the syntax to scan the ZEND/ZEND_LANGUAGE_SCANNER.L file first

Add the following code:

<ST_IN_SCRIPTING> "int" {return t_function_return_int;} <ST_IN_SCRIPTING> "bool" {return t_function_return_object;} <ST_IN_SCRIPTING> "Object" {return t_function_return_object;} <ST_IN_SCRIPTING> "Resource" {return t_function_return_resource;}

The meaning is simple, the scanner scans to the keyword int, bool, object, resource, array, return the corresponding t_function_*, this is a token,

Scanner is handled differently depending on the token, the token must be defined in the Zend/zend_language_parser.y file first

Add the following code

......%token T_function_return_int%token T_function_return_bool%token T_function_return_string%token T_FUNCTION_ Return_object%token T_function_return_resource1 then adds token processing logic: 1function:t_function {$$.u.opline_num = CG (zend_ Lineno); $$.u.ea.var  = 0;}|   T_function_return_int t_function {$$.u.opline_num = CG (Zend_lineno); $$.u.ea.var = is_long;}|   T_function_return_bool t_function {$$.u.opline_num = CG (Zend_lineno); $$.u.ea.var = is_bool;}|   T_function_return_string t_function {$$.u.opline_num = CG (Zend_lineno); $$.u.ea.var = is_string;}|   T_function_return_object t_function {$$.u.opline_num = CG (Zend_lineno); $$.u.ea.var = is_object;}|   T_function_return_resource t_function {$$.u.opline_num = CG (Zend_lineno); $$.u.ea.var = is_resource;}|   T_array t_function {$$.u.opline_num = CG (Zend_lineno); $$.u.ea.var = Is_array;}

$$.u.ea.var stores the function return type, and finally takes him to match the return value type,

This allows the syntax interpreter to handle our new PHP syntax.

This is not enough, and you need to modify the processing logic of the function declaration definition

ZEND/ZEND_COMPILE.C:: Zend_do_begin_function_declaration......zend_op_array op_array;char *name = function_name-> U.constant.value.str.val;int Name_len = function_name->u.constant.value.str.len;int Function_type  = function _token->u.ea.var; Save the function type, added in the syntax interpreter: $$.u.ea.var = is_long;int Function_begin_line = function_token->u.opline_num;......op_ Array.function_name = Name;op_array.fn_type = Function_type; Save type to Op_array, op_array.return_reference = return_reference;op_array.fn_flags |= fn_flags;op_array.pass_rest_by _reference = 0; .....

PHP is to parse the PHP syntax to generate the corresponding opcode, the required environment, parameter information is saved to the Execute_data global variable, and finally through the EXECUTE function to execute the opcode,

So to do the processing will be to save the type of function to opcode: Op_array.fn_type = function_type;

Op_array is not fn_type, to modify the structure of Op_array, increase zend_uint fn_type;

(About opcode you can imagine from c to the assembly, my blog also has related articles, can refer to)

Finally, to modify the opcode function, the function returns return will generate token T_return,t_return will call different calback functions according to the type returned:

Zend_return_spec_const_handlerzend_return_spec_tmp_handlerzend_return_spec_var_handler

It has three callback, and if the return value is a CONST type of data, then Zend_return_spec_const_handler
The return value is temporary data, such as: return 1, then Zend_return_spec_tmp_handler
The return value is a variable, such as: return $a, Zend_return_spec_var_handler

So add the processing logic to these three callback functions:

Add the following code before the callback function return

if (eg (active_op_array)->fn_type > 0) && z_type_p (retval_ptr)! = eg (active_op_array)->fn_type) {Php_ ERROR_DOCREF0 (NULL tsrmls_dc,e_warning, "function name%s return a wrong type.", EG (Active_op_array)->function_name) ;}

Fn_type is compared to the type of the return value, and if there is no match, the warning is thrown.

I have patched, currently only support php5.3 version, there is need to take to play a play.

I do not know why the official does not support this grammar, I think it is quite necessary.

  • 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.