php字符串拼接语法糖,教你用两行代码给PHP7添加一个“非空合并”语法糖

我们知道从 PHP 5.3 起三元运算符 ? : 有一个写法简洁写法是这样的:

$a = 0;

$b = $a ?: 1; # $b === 1

这实际上相当于:

$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),用于简化 isset 的条件判断:

$b = $a ?? 1;

它相当于:

$b = isset($a) ? $a : 1;

仅仅是 isset 判断,在 为等值时还是会返回b 的值还是为 0 。

这个操作符的语法分析语句是:

| expr T_COALESCE expr

{ $$ = zend_ast_create(ZEND_AST_COALESCE,$3); }

如果想将 isset 换成 empty 的效果,也就是说在变量不存在或转换成 boolean 后为 false 都赋予其他值,需要这样写:

$b = $a ?? 1 ?: 1;

显然上面的表达式中中间一部分稍微有些多余,那么做些简化呢?

现在我想添加一个语法 ??: ,它的作用是对变量做 empty 的判断。也就是说达到上面 $a ?? 1 ?: 1 的效果:

$b = $a ??: 1;

改起来很简单,只需要将 ?:和 ?? 的分析合并一下(注意这里和上面所有的地方 $1 $2 等符号的数字表示的都是变量或者常量出现的位置顺序):

| expr T_COALESCE ':' expr

{ $$ = zend_ast_create(ZEND_AST_CONDITIONAL,zend_ast_create(ZEND_AST_COALESCE,$4),$4); }

仅仅只有两句,因为并没有在词法分析器中添加 Token,所以只能算是个语法糖。

重新编译一下之后就能看到效果啦。

测试:

$ /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

更多学习内容请访问:

总结

如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值