PHP运算符 ?? vs ?:

38 浏览
0 Comments

PHP运算符 ?? vs ?:

有人可以解释一下PHP中的三元运算符简写(?:)和空合并运算符(??)之间的区别吗?\n它们在什么情况下表现不同,以及是否有相同的情况(如果有的话)?\n$a ?: $b\n与\n$a ?? $b

0
0 Comments

PHP中的操作符??和?:的出现是为了解决以下问题。如果使用简化的三元运算符,当$_GET['username']未设置时会引发一个提示:

$val = $_GET['username'] ?: 'default';

因此,你需要像这样处理:

$val = isset($_GET['username']) ? $_GET['username'] : 'default';

null合并运算符等效于上面的语句,并且如果$_GET['username']未设置或为null,则返回'default':

$val = $_GET['username'] ?? 'default';

注意,它不检查真实性。它只检查它是否设置且不为null。

你也可以这样做,返回第一个已定义(设置且不为null)的值:

$val = $input1 ?? $input2 ?? $input3 ?? 'default';

现在这是一个合适的合并运算符。

为了不引发提示,应该使用$var = empty($other_var) ? 'default_value' : $other_var;。注意,这不包括''、null、false和0。

0
0 Comments

PHP中的运算符??和?:之间的区别以及出现的原因和解决方法

在PHP交互模式下运行了下面的代码(在终端上运行php -a)。每一行的注释显示了结果。

var_export (false ?? 'value2');   // false
var_export (true  ?? 'value2');   // true
var_export (null  ?? 'value2');   // value2
var_export (''    ?? 'value2');   // ""
var_export (0     ?? 'value2');   // 0
var_export (false ?: 'value2');   // value2
var_export (true  ?: 'value2');   // true
var_export (null  ?: 'value2');   // value2
var_export (''    ?: 'value2');   // value2
var_export (0     ?: 'value2');   // value2

**Null合并运算符 `??`**

- `??`类似于一个“门”,只允许`NULL`通过。

- 所以,除非第一个参数恰好是`NULL`,否则它总是返回第一个参数。

- 这意味着`??`与`( !isset() || is_null() )`相同。

使用`??`的方式:

- 缩短`!isset() || is_null()`的检查。

- 例如:`$object = $object ?? new objClassName();`

堆叠Null合并运算符:

$v = $x ?? $y ?? $z; 
// 这是一系列“SET && NOT NULL”:
if($x && !is_null($x)){ 
    return $x; 
} else if($y && !is_null($y)){ 
    return $y; 
} else { 
    return $z; 
}

**三元运算符 `?:`**

- `?:`类似于一个门,可以让任何“假值”通过 - 包括`NULL`。

- 任何“假值”:`0`,空字符串,`NULL`,`false`,`!isset()`,`empty()`

- 与旧的三元运算符相同:`X ? Y : Z`

- 注意:对于未定义(未设置或`!isset()`)的变量,`?:`会抛出PHP NOTICE。

使用`?:`的方式:

- 检查`empty()`,`!isset()`,`is_null()`等。

- 将三元操作缩短为`!empty($x) ? $x : $y`,变为`$x ?: $y`。

- 将`if(!$x) { echo $x; } else { echo $y; }`缩短为`echo $x ?: $y`。

堆叠三元运算符:

echo 0 ?: 1 ?: 2 ?: 3; // 1
echo 1 ?: 0 ?: 3 ?: 2; // 1
echo 2 ?: 1 ?: 0 ?: 3; // 2
echo 3 ?: 2 ?: 1 ?: 0; // 3
echo 0 ?: 1 ?: 2 ?: 3; // 1
echo 0 ?: 0 ?: 2 ?: 3; // 2
echo 0 ?: 0 ?: 0 ?: 3; // 3

将两者结合使用可以缩短以下代码:

if(isset($_GET['name']) && !is_null($_GET['name'])) {
    $name = $_GET['name'];
} else if(!empty($user_name)) {
     $name = $user_name; 
} else {
    $name = 'anonymous';
}

缩短为:

$name = $_GET['name'] ?? $user_name ?: 'anonymous';

很酷,对吧? 🙂

这种方法很好,只是有一个错误:将`if(!$x) { echo $x; } else { echo $y; }`缩短为`echo $x ?: $y`。两者是不相等的。条件必须是`if($x)`,没有否定。这个例子让我了解了这个新的运算符的一些知识,所以我给了一个赞。

在PHP中,请始终使用`elseif`作为一个单词,以符合PSR-12编码规范。我知道你只是在做一个演示,但是`isset($_GET['name']) && !is_null($_GET['name'])`本身就是冗余的检查。

这是一个非常好的解释,但不要错过这一行:`Note: ?: will throw PHP NOTICE on undefined (unset or !isset()) variables`,如果无法保证一个变量(尤其是一个数组索引)已经设置,仍然需要使用`!empty()`或`isset()`(取决于你需要的行为)。

0
0 Comments

PHP运算符??和?:的区别以及解决方法

在PHP中,Elvis运算符`?:`和Null合并运算符`??`的作用是相似的,都是用来简化代码中的条件表达式。然而,它们之间存在一些细微的差别。

Elvis运算符`?:`会返回第一个参数,如果第一个参数包含一个“真值”(参见PHP手册中“Loose comparisons with ==”表中哪些值被松散地等同于`true`),否则返回第二个参数。它的语法如下:

$result = $var ?: 'default';
//等同于
$result = $var ? $var : 'default';

Null合并运算符`??`会返回第一个参数,如果第一个参数已经设置并且不为`null`,否则返回第二个参数。它的语法如下:

$result = $var ?? 'default';
//等同于
$result = isset($var) ? $var : 'default';

当第一个参数为`null`时,它们基本上是相同的,唯一的区别是当使用未定义的变量时,Null合并运算符不会输出一个`E_NOTICE`错误。根据PHP 7.0的迁移文档,Null合并运算符是为了简化在使用`isset()`函数进行判断的情况而添加的。如果第一个操作数存在且不为`NULL`,它返回第一个操作数;否则返回第二个操作数。

下面是一些示例代码来演示这一点:

$a = null;
print $a ?? 'b'; // 输出 b
print "\n";
print $a ?: 'b'; // 输出 b
print "\n";
print $c ?? 'a'; // 输出 a
print "\n";
print $c ?: 'a'; // 输出 Notice: Undefined variable: c in /in/apAIb on line 14
print "\n";
$b = array('a' => null);
print $b['a'] ?? 'd'; // 输出 d
print "\n";
print $b['a'] ?: 'd'; // 输出 d
print "\n";
print $b['c'] ?? 'e'; // 输出 e
print "\n";
print $b['c'] ?: 'e'; // 输出 Notice: Undefined index: c in /in/apAIb on line 33
print "\n";

以上代码中,使用`??`运算符的地方不会出现Notice错误,而使用`?:`运算符的地方会出现Notice错误。然而,即使有Notice错误,PHP也会返回相同的结果。

当第一个参数不为`null`时,它们之间的区别就显现出来了。Null合并运算符`??`将始终返回第一个参数,而Elvis运算符`?:`只有在第一个参数为真值时才会返回第一个参数,这依赖于PHP如何将值转换为布尔类型。

例如:

$a = false ?? 'f'; // $a的值为 false
$b = false ?: 'g'; // $b的值为 'g'

需要注意的是,Null合并运算符`??`可以进行链式操作。例如:

$b = []; var_dump($b['a']['b']['c'] ?? 'default'); // 输出 'default'

或者在对象中使用:

$b = new Foo; var_dump($b->a()->b()->c() ?? 'default'); // 输出 'default'

需要注意的是,对于`$a = [];`的情况,它们的行为也是不同的。可以参考链接:[3v4l.org/iCCa0](https://3v4l.org/iCCa0)

,Elvis运算符`?:`和Null合并运算符`??`在某些情况下可以互换使用,但在一些特定的情况下存在细微的差别。根据具体的需求和代码兼容性,选择合适的运算符来简化代码。

0