教你用两行代码给PHP7添加一个“非空合并”语法糖
我们知道从 PHP 5.3 起三元运算符? ? <?php $a = 0; $b = $a ?: 1; # $b === 1
这实际上相当于: <?php $a = 0; $b = $a ? $a : 1; # $b === 1
在 PHP5 中,语法分析是这样写的: | expr '?' { zend_do_begin_qm_op(&$1,&$2 TSRMLS_CC); } expr ':' { zend_do_qm_true(&$4,&$2,&$5 TSRMLS_CC); } expr { zend_do_qm_false(&$$,&$7,&$5 TSRMLS_CC); } | expr '?' ':' { zend_do_jmp_set(&$1,&$3 TSRMLS_CC); } expr { zend_do_jmp_set_else(&$$,&$5,&$3 TSRMLS_CC); }
在 PHP7 中,由于 AST(抽象语法树)的引入,语法分析有些简化: | expr '?' expr ':' expr { $$ = zend_ast_create(ZEND_AST_CONDITIONAL,$1,$3,$5); } | expr '?' ':' expr { $$ = zend_ast_create(ZEND_AST_CONDITIONAL,NULL,$4); }
PHP7 中语法分析之后都是写到 AST 的节点上。从上面可以看出,简化的 ?: 和完整的三元表达式的区别就是节点中间的值为 NULL。 PHP7 添加了一个合并操作符(T_COALESCE),用于简化? <?php $b = $a ?? 1;
它相当于: <?php $b = isset($a) ? $a : 1;
仅仅是? 这个操作符的语法分析语句是: | expr T_COALESCE expr { $$ = zend_ast_create(ZEND_AST_COALESCE,$3); }
如果想将? <?php $b = $a ?? 1 ?: 1;
显然上面的表达式中中间一部分稍微有些多余,那么做些简化呢? 现在我想添加一个语法? <?php $b = $a ??: 1;
改起来很简单,只需要将? | expr T_COALESCE ':' expr { $$ = zend_ast_create(ZEND_AST_CONDITIONAL,zend_ast_create(ZEND_AST_COALESCE,$4),$4); }
仅仅只有两句,因为并没有在词法分析器中添加? 重新编译一下之后就能看到效果啦。 测试: $ /usr/local/php/bin/php -r "$a = 0; echo $a ?? 1,PHP_EOL;" 0 $ /usr/local/php/bin/php -r "$a = 0; echo $a ??: 1,PHP_EOL;" 1
更多学习内容请访问: 腾讯T3-T4标准精品PHP架构师教程目录大全,只要你看完保证薪资上升一个台阶(持续更新) ? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |