使用返回时的PHP Shorthand If/Else

14

有几种简洁的方式可以在PHP中编写缩写。

不太常见但最短的例子:

!isset( $search_order ) && $search_order = 'ASC';

更常见但略长的方法:

!isset( $search_order ) ? $search_order = 'ASC' : $search_order = NULL;

我们甚至可以将上面的例子结合起来,形成一个惊人的速记:
!isset( $_POST['unique_id'] ) && preg_match( '/^[a-zA-Z0-9]{8}$/', $_POST['unique_id'] ) ? $post_unique_id = $_POST['unique_id'] : $post_unique_id = NULL;

但是我们如何将上面的例子用于函数和返回值中,例如:
function filter_gender_request($data) {  
    preg_match('/(fe)?male/i', $data, $data);
    isset($data[0]) && return $data[0]; // It doesn't work here with return
}

同时,如果我这样声明,而不是isset($data[0]) && return $data[0];那么一切都会如预期那样工作:
if (isset($data[0]) ) {
    return $data[0];
}

我在这里做错了什么?如果最简单的第一个例子在函数外面无需问题地运行,那么为什么使用返回语句时它不能工作呢?

有没有可能在返回语句中使用速记方式?


6
像你展示的简洁代码不太易读,因此质量较差。写出if语句来避免未来的麻烦,让自己不必解密最初想要写的是什么。 - zzzzBov
1
个人而言,我使用:$search_order = (!isset( $search_order ) ? 'ASC' : NULL); - user1646111
我不确定这样写能节省什么——10个按键?[这是一条很好的编程建议] (http://www.codinghorror.com/blog/2008/06/coding-for-violent-psychopaths.html)。 - Buggabill
读取 !isset( $search_order ) && $search_order = 'ASC'; 的问题是什么?那使用简写的意义何在? - Ilia
6个回答

36

使用您当前的语法,当$data[0]未设置时,您希望您的函数返回什么?您肯定不希望您的函数基于某个条件却返回任何内容。

我唯一能看到的替代方案是三元运算符,在这里,当$data[0]未设置时,您可以返回其他内容:

return isset($data[0]) ? $data[0] : null; 

谢谢,Nick!我试了一下,你的例子可行!此时我不在乎它是否设置为NULL,因为它将在稍后处理,如果没有设置,它将被设置为NULL - Ilia
@IliaRostovtsev,这可能是您最好的选择,也是实现您结果的最直接方法。别忘了选择正确的答案,这样您的问题就不会在未回答的状态下挂起。 - Jason
杰森,不会的!我从来没有真正忘记过!谢谢大家!! :) - Ilia

28

给未来的谷歌搜索者。

使用 PHP 7 的 null 合并运算符 (??)。

return $data[0] ?? null; 

1
感谢分享。 - Ilia

12

你那个惊人的快捷方式实际上是相当丑陋的代码。你滥用了三目运算符,而且那段代码实际上比起手写代码来说更难读懂和维护。人们期望三目运算符执行测试并返回一个真或假的值。在其中进行赋值操作是不正常的行为。


4
你提出的观点非常好。代码确实非常巧妙,但是维护起来会很麻烦。 - Ibu
谢谢,马克,我同意!如果任何使用快捷键都是滥用的话,那么一开始有快捷方式的意义是什么呢? - Ilia
设置默认值的新方式$foo = isset($foo) ?: 'default value'非常方便,但这不是对语法的滥用,因为它是PHP 5.4的内置语言特性。至于其他快捷方式,!isset (...) && $foo ='bar'在我看来是错误的,因为其中有一个隐含的if()条件。而且在if()中看到赋值操作会让我想起警报。我会自动将其视为“应该是 $foo == 'bar'”而不是赋值。 - Marc B
6
这个答案有一个开放的 Meta 讨论,链接在这里:Review audit seems wrong - Joris Van Regemortel

4

你的代码问题在于你试图在三目运算符表达式中执行一个 return 语句。三目运算符通常会导致一个赋值,例如:

$message = is_error() ? get_error() : 'No Errors';

这导致根据 is_error() 的返回值进行对 $message 进行赋值。你的代码试图在操作中处理程序控制语句,但是 return 不能被分配给变量。
因此,其他用户发布的内容更适合你的情况。

2

好的,我不知道你在做什么,但是这个应该可以解决问题:

return ( isset($data[0]) ? $data[0] : false);

1
同意这里的回答,使用速记代码后离开一段时间再回来或者更糟糕的是另一个开发人员在未来阅读时会变得更难以阅读。
想象一下自己有一个500行的小脚本文件,其中有40行速记的elseif,你会尝试添加或更改代码吗?
特别是当主题或内容不是您熟悉的东西时,调试或添加变得非常头疼。
这种写法更容易管理,不管它是关于什么的,它只是代码。
if ($var == 'unicorns')
  {
    $this->remove_horn;
  }
elseif ($var == 'horse')
 {
   $this->glue_on_horn;
 }
else
  {
    $this->must_be_a_zebra;
  }

只是说一下


你认为在编写代码和开发过程中是否有时不需要考虑可维护性?即使是一个快速脚本、只做一件事的小页面,也应该整洁、规范地编写,并遵循当前和未来的标准,以便于维护... - James
4
如果是这种情况,你的例子应该使用 switch 语句。 - Cerad
我了解那是你的个人偏好,这就是全部。此外,OP使用了ifelse... ;) - James

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接