> 백엔드 개발 > PHP7 > 본문

두 줄의 코드를 사용하여 '비어 있지 않은 병합' 구문 설탕을 PHP7에 추가하는 방법을 가르칩니다.

藏色散人
풀어 주다: 2023-02-17 15:02:01
앞으로
3459명이 탐색했습니다.

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

<?php
$a = 0;
$b = $a ?: 1; # $b === 1
로그인 후 복사

这实际上相当于:

<?php
$a = 0;
$b = $a ? $a : 1; # $b === 1
로그인 후 복사

在 PHP5 中,语法分析是这样写的:

|   expr &#39;?&#39; { zend_do_begin_qm_op(&$1, &$2 TSRMLS_CC); }
    expr &#39;:&#39; { zend_do_qm_true(&$4, &$2, &$5 TSRMLS_CC); }
    expr     { zend_do_qm_false(&$$, &$7, &$2, &$5 TSRMLS_CC); }
|   expr &#39;?&#39; &#39;:&#39; { zend_do_jmp_set(&$1, &$2, &$3 TSRMLS_CC); }
    expr     { zend_do_jmp_set_else(&$$, &$5, &$2, &$3 TSRMLS_CC); }
로그인 후 복사

在 PHP7 中,由于 AST(抽象语法树)的引入,语法分析有些简化:

|   expr &#39;?&#39; expr &#39;:&#39; expr
        { $$ = zend_ast_create(ZEND_AST_CONDITIONAL, $1, $3, $5); }
|   expr &#39;?&#39; &#39;:&#39; expr
        { $$ = zend_ast_create(ZEND_AST_CONDITIONAL, $1, NULL, $4); }
로그인 후 복사

PHP7 中语法分析之后都是写到 AST 的节点上。从上面可以看出,简化的 ?: 和完整的三元表达式的区别就是节点中间的值为 NULL。

PHP7 添加了一个合并操作符(T_COALESCE),用于简化 isset 的条件判断:

<?php
$b = $a ?? 1;
로그인 후 복사

它相当于:

<?php
$b = isset($a) ? $a : 1;
로그인 후 복사

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

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

|   expr T_COALESCE expr
        { $$ = zend_ast_create(ZEND_AST_COALESCE, $1, $3); }
로그인 후 복사

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

<?php
$b = $a ?? 1 ?: 1;
로그인 후 복사

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

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

<?php
$b = $a ??: 1;
로그인 후 복사

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

|   expr T_COALESCE &#39;:&#39; expr
        { $$ = zend_ast_create(ZEND_AST_CONDITIONAL,
            zend_ast_create(ZEND_AST_COALESCE, $1, $4), NULL, $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
로그인 후 복사

위 내용은 두 줄의 코드를 사용하여 '비어 있지 않은 병합' 구문 설탕을 PHP7에 추가하는 방법을 가르칩니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:segmentfault.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿