133

许多编程语言都有一个合并函数(返回第一个非 NULL 值,例如)。PHP,遗憾的是在 2009 年没有。

在 PHP 本身获得合并函数之前,在 PHP 中实现一个的好方法是什么?

4

9 回答 9

199

php 5.3 中有一个新的运算符可以执行此操作:?:

// A
echo 'A' ?: 'B';

// B
echo '' ?: 'B';

// B
echo false ?: 'B';

// B
echo null ?: 'B';

来源:http ://www.php.net/ChangeLog-5.php#5.3.0

于 2009-12-12T01:32:16.670 回答
69

PHP 7 引入了一个真正的合并操作符

echo $_GET['doesNotExist'] ?? 'fallback'; // prints 'fallback'

如果前面的值??不存在或者是null后面的值??

对上述?:运算符的改进是,??它还可以处理未定义的变量而不抛出E_NOTICE.

于 2015-06-24T08:35:01.407 回答
30

在谷歌上首次点击“php coalesce”。

function coalesce() {
  $args = func_get_args();
  foreach ($args as $arg) {
    if (!empty($arg)) {
      return $arg;
    }
  }
  return NULL;
}

http://drupial.com/content/php-coalesce

于 2009-06-18T15:51:34.407 回答
18

我真的很喜欢 ?: 运算符。不幸的是,它还没有在我的生产环境中实现。所以我使用这个等价物:

function coalesce() {
  return array_shift(array_filter(func_get_args()));
}
于 2011-01-14T04:58:25.753 回答
10

值得注意的是,由于 PHP 对未初始化变量和数组索引的处理,任何类型的合并函数的使用都是有限的。我希望能够做到这一点:

$id = coalesce($_GET['id'], $_SESSION['id'], null);

但是,在大多数情况下,这会导致 PHP 出错并显示 E_NOTICE。在使用变量之前测试变量是否存在的唯一安全方法是直接在 empty() 或 isset() 中使用它。如果您知道合并中的所有选项都已知已初始化,则 Kevin 建议的三元运算符是最佳选择。

于 2010-05-16T19:03:07.577 回答
6

确保您确定您希望此函数如何与某些类型一起使用。PHP 有各种各样的类型检查或类似功能,因此请确保您知道它们是如何工作的。这是 is_null() 和 empty() 的示例比较

$testData = array(
  'FALSE'   => FALSE
  ,'0'      => 0
  ,'"0"'    => "0"  
  ,'NULL'   => NULL
  ,'array()'=> array()
  ,'new stdClass()' => new stdClass()
  ,'$undef' => $undef
);

foreach ( $testData as $key => $var )
{
  echo "$key " . (( empty( $var ) ) ? 'is' : 'is not') . " empty<br>";
  echo "$key " . (( is_null( $var ) ) ? 'is' : 'is not')  . " null<br>";
  echo '<hr>';
}

如您所见,empty() 对所有这些都返回 true,但 is_null() 仅对其中 2 个返回 true。

于 2009-06-18T16:43:18.600 回答
2

我正在扩展Ethan Kent发布的答案。由于array_filter的内部工作原理,该答案将丢弃评估为 false 的非空参数,这不是coalesce函数通常所做的。例如:

echo 42 === coalesce(null, 0, 42) ? 'Oops' : 'Hooray';

哎呀

为了克服这个问题,需要第二个参数和函数定义。可调用函数负责告知array_filter是否将当前数组值添加到结果数组中:

// "callable"
function not_null($i){
    return !is_null($i);  // strictly non-null, 'isset' possibly not as much
}

function coalesce(){
    // pass callable to array_filter
    return array_shift(array_filter(func_get_args(), 'not_null'));
}

如果您可以简单地将issetor'isset'作为第二个参数传递给,那就太好了array_filter,但没有这样的运气。

于 2013-02-20T22:27:36.273 回答
0

我目前正在使用它,但我想知道它是否无法通过 PHP 5 中的一些新功能进行改进。

function coalesce() {
  $args = func_get_args();
  foreach ($args as $arg) {
    if (!empty($arg)) {
    return $arg;
    }
  }
  return $args[0];
}
于 2009-06-18T15:54:44.377 回答
0

PHP 5.3+,带闭包:

function coalesce()
{
    return array_shift(array_filter(func_get_args(), function ($value) {
        return !is_null($value);
    }));
}

演示:https ://eval.in/187365

于 2014-09-02T20:21:54.690 回答