1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > php自定义函数返回值的深入实例详解

php自定义函数返回值的深入实例详解

时间:2022-10-07 01:32:05

相关推荐

php自定义函数返回值的深入实例详解

后端开发|php教程

自定义,php,实例,返回,函数,深入

后端开发-php教程

函数的返回值

lol自动登录源码,ubuntu ssd安装,tomcat的部署及应用,做爬虫工作,php培训学校选兄弟连,上海市场seo优化有哪些lzw

PHP中函数都有返回值,没return返回null

微信抢红包网站源码,查看安装软件ubuntu,tomcat1013无标题,机械爬虫挑战,php网络安全知识,广州seo‘’lzw

(1)return语句

刷客cms源码,vscode的nginx,ubuntu图文,tomcat进程占用,sqlite打不开的原因,typecho 图片上传插件,前端游戏框架制作阴阳师,视频爬虫脚本代码是什么,php 汉字转换,宿迁seo推广价位,天龙八部网站模板下载,展示栏网页模板,publisher模板下载lzw

从Zend/zend_language_parser.y文件中可以确认其生成中间代码调用的是zend_do_return函数。

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_method_call(expr)) { zend_do_end_variable_parse(expr, BP_VAR_W, 0 TSRMLS_CC);/* 处理返回引用 */ } else { zend_do_end_variable_parse(expr, BP_VAR_R, 0 TSRMLS_CC);/* 处理常规变量返回 */ } } ...// 省略,取其他中间代码操作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);}/* }}} */

生成中间代码为ZEND_RETURN。第一个操作数的类型在返回值为可用的表达式时,其类型为表达式的操作类型,否则类型为IS_CONST。这在后续计算执行中间代码函数时有用到。根据操作数的不同,ZEND_RETURN中间代码会执行ZEND_RETURN_SPEC_CONST_HANDLER,ZEND_RETURN_SPEC_TMP_HANDLER或ZEND_RETURN_SPEC_TMP_HANDLER。这三个函数的执行流程基本类似,包括对一些错误的处理。这里我们以ZEND_RETURN_SPEC_CONST_HANDLER为例说明函数返回值的执行过程:

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_CONST || IS_CONST == IS_TMP_VAR) {/* Not supposed to happen, but well allow it */ zend_error(E_NOTICE, "Only variable references \should be 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 return 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 && !0) {/* undo the effect of get_zval_ptr_ptr() */ PZVAL_LOCK(*retval_ptr_ptr);}zend_error(E_NOTICE, "Only variable references \ should be 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Œď×1 (*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 var */ 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); // Ǔǔĉˆșʒ}

函数的返回值在程序执行时存储在*EG(return_value_ptr_ptr)。ZEND内核对值返回和引用返回作了区别,并且在此基础上对常量,临时变量和其他类型的变量在返回时作了不同的处理。在return执行完之后,ZEND内核通过调用zend_leave_helper_SPEC函数,清除函数内部使用的变量等。这也是ZEND内核自动给函数加上NULL返回的原因之一。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。