简体   繁体   English

在PHP中使用三元运算符仅返回true

[英]Using the ternary operator in PHP for true returns only

Been playing around a bit with both the ternary operator and null coalesce these past few weeks and really enjoy the way that it's been able to simplify a lot of my logic, especially in places where I would previously have to stack a series of if (!empty($variable)) -kinds of lines to an already annoyingly large if/else statement. 在过去的几周中,一直与三元运算符和null合并一起玩耍,并且真的很喜欢它简化了很多逻辑的方式,尤其是在我以前不得不堆叠一系列if (!empty($variable))种类繁多的if/else语句行。 Now I can just $object->attribute = $source->attribute ?? null 现在我可以$object->attribute = $source->attribute ?? null $object->attribute = $source->attribute ?? null , assuming I don't know if there will be an attribute in source or not. $object->attribute = $source->attribute ?? null ,假设我不知道source是否会有属性。

Now, the question that I'm having issues with is trying to figure out how to best use this for logging. 现在,我遇到的问题是试图找出如何最好地使用它进行日志记录。 Say I've got a function like: 说我有一个像这样的功能:

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;
    }
}

Fairly straightforward; 非常坦率的; you send addToQueue() two arguments, the field and the id , and then it does three checks. 您向addToQueue()发送两个参数,即fieldid ,然后执行三个检查。 Are any of them null ? 它们是否为null Then return false . 然后返回false Is field something other than name or id ? field不是nameid以外的其他内容吗? Then return false . 然后返回false Is this entry already in the Queue? 该条目已经在队列中了吗? Then return true (since we're interested in making sure that the entry is in the queue, not whether we added it right now or not). 然后返回true (因为我们有兴趣确保该条目位于队列中,而不是是否立即添加该条目)。 And, finally, if the pair is not in the queue, we add it and - again - return true . 最后,如果该对不在队列中,我们将其添加并再次返回true

Now; 现在; so far so good; 到现在为止还挺好; right? 对? Doesn't seem to be an issue here, even though I see how I could probably make the logic inside of the function a little neater. 尽管我知道如何使函数内部的逻辑变得更加整洁,但这似乎不是问题。 The problem comes in my usage of it. 问题出在我的使用上。 Essentially, what I want to do is something like this - but with ternary operators: 本质上,我想做的就是这样-但是使用三元运算符:

if (QueueHandler::addToQueue($input->field, $input->value) == true) { $app->log->info($input->field . '/' . $input->value . ' added to queue.'; }

I want it to do something if the operation it carries out evaluates as true, but do nothing if it evaluates as false. 我希望它执行的操作评估为真,但是如果评估为假,则不执行任何操作。

And yes, I know , it's called Ternary because you need three operations, but since PHP allows you to isset($variable) ?: echo 'Dude. It\\'s not set...'; 是的, 我知道 ,它被称为三元,因为您需要执行三个操作,但是由于PHP允许您进行isset($variable) ?: echo 'Dude. It\\'s not set...'; isset($variable) ?: echo 'Dude. It\\'s not set...'; nowadays, I figured there should be a way to do the opposite, right? 如今,我认为应该有一种相反的方法,对吗?

The ?? ?? operator is right associative (Source) 运算符是正确的关联 (源)

It means: 它的意思是:

$field??$id??null == null 

If $field is not set or null then that collapses to: 如果未设置$field或为null,则折叠为:

$id??null==null

If $id is not set or null that collapses to: 如果未设置$id或null,则折叠为:

null==null 

That expression will always be true since the null is swallowed by the ?? 该表达式将始终为true,因为null被??吞没了。 operator. 操作员。 This means $field??$id??null==null will never evaluate to a falsey value. 这意味着$field??$id??null==null将永远不会得出假值。

You need to be explicit if you want to force precedence: 如果要强制优先级,则需要明确:

($field??$id??null) == null

The ternary is shorthand for IF ELSE. 三元是IF ELSE的简写。

Even the code you mentioned isset($variable) ?: echo 'Dude. It\\'s not set...'; 甚至您提到的代码都是isset($variable) ?: echo 'Dude. It\\'s not set...'; isset($variable) ?: echo 'Dude. It\\'s not set...'; is doing that (it will return $variable if isset is true), even though it appears you have just added the else part. 这样做(如果isset为true,它将返回$ variable),即使看起来您刚刚添加了else部分。 So there is no "opposite" there is only IF and ELSE 因此,没有“对立”,只有IF和ELSE

For example: 例如:

$a = 'foo';
echo $a ?: 'bar'; // 'foo'

So, you current code is simple 所以,您当前的代码很简单

if (QueueHandler::addToQueue($input->field, $input->value) == true) {    
    $app->log->info($input->field . '/' . $input->value . ' added to queue.'; 
}

As addToQueue returns bool, you can simplify to: addToQueue返回bool时,您可以简化为:

if (QueueHandler::addToQueue($input->field, $input->value)) {    
    $app->log->info($input->field . '/' . $input->value . ' added to queue.'; 
}

Now you're trying to use this: 现在,您尝试使用此功能:

!QueueHandler::addToQueue($input->field, $input->value) ?: $app->log->info($input->field . '/' . $input->value . ' added to queue.';

I don't think it is more readable then previous examples. 我认为它比以前的示例更具可读性。

Wanna play with ternarys? 想和三元玩吗?

Do like it: 喜欢它:

function addToQueue($field, $id)
{
    return ($field??$id??null) == null?false:($field != 'name' && $field != 'id')?false:
        (Queue::where($field, $id)->count() != 0)?true:Queue::insert([$field => $id])?true:true;
}

No one will understand, not even you. 没有人会明白,甚至你也不会。 Every time you have to change it you will ask yourself why you did this way, but it will get your phpunit code coverage easier. 每次必须更改它时,您都会问自己为什么这样做,但这将使您的phpunit代码覆盖范围更加容易。

Now seriously, apokryfos spotted it. 现在很严重,apokryfos发现了它。 But you have to ask yourself what are you getting out of using ternarys. 但是您必须问自己,使用三元组会带来什么。

It's really good for things like: 它对于诸如以下的事情确实非常有用:

function getClub(){
    return $this->isClubVisible()? $this->club: null;
}

And every operation that you would solve with an if/else but as you can see if you overuse it, it will get really messy and unreadable. 而且,如果使用if / else可以解决每一个操作,但是您会发现是否过度使用它,那么它会变得非常混乱且难以理解。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM