当前位置: 首页 > 后端技术 > PHP

isset在php5.6-和php7.0+

时间:2023-03-29 13:44:03 PHP

中的一些区别今天在公司实现一个模块功能时写了如下代码:classProductCategory{constTYPES=[1=>'type1',2=>'type2',];publicfunctiongetType(){returnisset(self::TYPES[$this->type])?self:TYPES[$this->type]:'unrecognized_type';}}报错,编译阶段失败。Fatalerror:Cannotuseisset()ontheresultofanexpression(youcanuse"null!==expression"instead)错误信息的意思很明显,但是我的代码isset不是表达式,这让我百思不得其解。带着疑惑在家重新敲了敲上面的代码,编译运行正常。使用php-v检查版本,7.1。但是公司的开发机运行的是php5.6。那么,为什么会有这样的差异呢?isset的底层实现只能看源码。众所周知,isset不是一个函数,而是一个语法结构,所以如果出现错误,在编译阶段就会出错。比较php5.6中zend_language_parse.y的1283行中php5.6和php7.0+版本的zend_language_parse.yisset_variable:variable{zend_do_isset_or_isempty(ZEND_ISSET,&$$,&$1TSRMLS_CC);}|expr_without_variable{zend_error_noreturn(E_COMPILE_ERROR,"不能在resultpress()上使用isset()的表达式,你可以使用\"null!==expression\"代替)");};显然,在词法分析过程中,类经常数量被定义为非变量。看一下expr_without_variable的定义。从文件的第776行到第858行,我们找到了这样一个定义:|combined_scalar_offset{zend_do_end_variable_parse(&$1,BP_VAR_R,0TSRMLS_CC);}查看combined_scalar_offset定义:general_constant'['dim_offset']'{zend_do_begin_variable_parse(TSRMLS_C);fetch_array_dim(&$$,&$1,&$3TSRMLS_CC);再看看general_constant的定义:class_constant{$$=$1;它被定义为非变量,因此会引发编译错误。在php7.0+版本中,combined_scalar_offset{zend_do_end_variable_parse(&$1,BP_VAR_R,0TSRMLS_CC);}已移除。所以编译通过,运行成功。不知道这是不是bug,不过还是5.6的特性~~~