在过去的几个星期里一直在玩三元运算符和null合并,并且真正享受它能够简化我的逻辑的方式,特别是在我之前必须堆叠一系列的逻辑上if (!empty($variable))
- 已经烦人的if/else
语句的各种行。现在我可以$object->attribute = $source->attribute ?? null
,假设我不知道source
中是否有属性。
现在,我遇到问题的问题是试图找出如何最好地将其用于日志记录。说我有一个像以下的功能:
public static function addToQueue($field, $id)
{
if ($field ?? $id ?? null == null) {
return false;
} elseif ($field != 'name' && $field != 'id') {
return false;
} elseif (Queue::where($field, $id)->count() != 0) {
return true;
} else {
Queue::insert([$field => $id]);
return true;
}
}
相当简单;你发送addToQueue()
两个参数,field
和id
,然后进行三次检查。他们中的任何一个null
?然后返回false
。 field
或name
以外的其他内容是id
吗?然后返回false
。此条目是否已在队列中?然后返回true
(因为我们有兴趣确保条目在队列中,而不是我们现在是否添加它)。最后,如果该对不在队列中,我们将其添加 - 再次 - 返回true
。
现在;到现在为止还挺好;对?这似乎不是一个问题,即使我看到我怎么可能使函数内部的逻辑更整洁。问题在于我使用它。从本质上讲,我想要做的就是这样 - 但是使用三元运算符:
if (QueueHandler::addToQueue($input->field, $input->value) == true) { $app->log->info($input->field . '/' . $input->value . ' added to queue.'; }
如果它执行的操作评估为true,我希望它能做某些事情,但如果评估为false则不执行任何操作。
是的,我知道,它叫做Ternary,因为你需要三个操作,但是现在PHP允许你isset($variable) ?: echo 'Dude. It\'s not set...';
,我认为应该有一种做相反的方法吧?
答案 0 :(得分:2)
??
运算符右关联 (Source)
这意味着:
$field??$id??null == null
如果未设置$field
或为null,则折叠为:
$id??null==null
如果未设置$id
,则归零:
null==null
由于??
运算符吞下了null,因此该表达式始终为true。这意味着$field??$id??null==null
永远不会评估为假值。
如果要强制优先,则需要明确:
($field??$id??null) == null
答案 1 :(得分:0)
三元是IF ELSE的简写。
即使您提到的代码isset($variable) ?: echo 'Dude. It\'s not set...';
正在执行此操作(如果isset为true,它将返回$ variable),即使看起来您刚刚添加了else部分。所以没有"反对"只有IF和ELSE
例如:
$a = 'foo';
echo $a ?: 'bar'; // 'foo'
答案 2 :(得分:0)
所以,你当前的代码很简单
if (QueueHandler::addToQueue($input->field, $input->value) == true) {
$app->log->info($input->field . '/' . $input->value . ' added to queue.';
}
当addToQueue
返回bool时,您可以简化为:
if (QueueHandler::addToQueue($input->field, $input->value)) {
$app->log->info($input->field . '/' . $input->value . ' added to queue.';
}
现在你正在尝试使用它:
!QueueHandler::addToQueue($input->field, $input->value) ?: $app->log->info($input->field . '/' . $input->value . ' added to queue.';
我不认为它比以前的例子更具可读性。