用于 PHP 的聚合函数 Coalesce? ?

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

在 PHP 本身得到一个聚合函数之前,如何在 PHP 中实现一个聚合函数?

65667 次浏览

“ php 凝聚”首次在谷歌上出现。

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

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

我目前正在使用它,但是我想知道它是否可以通过 PHP5中的一些新特性得到改进。

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

确保准确地确定希望该函数如何处理某些类型。PHP 有各种各样的类型检查或类似的函数,所以一定要知道它们是如何工作的。这是 is _ null ()和 void ()的一个示例比较

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

正如您所看到的,对于所有这些函数,void ()返回 true,但是对于其中的2个函数,is _ null ()只返回 true。

在 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

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

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

但是,在大多数情况下,这将导致 PHP 使用 E _ NOTICE 出错。在使用变量之前测试其存在性的唯一安全方法是直接在 void ()或 isset ()中使用它。凯文建议的三元运算符是最好的选择,如果你知道所有的选项在你的合并已知被初始化。

我真的很喜欢?操作员。不幸的是,它还没有在我的生产环境中实现。所以我用了相当于这个的东西:

function coalesce() {
return array_shift(array_filter(func_get_args()));
}

我正在扩展 伊森 · 肯特发布的答案。这个答案将丢弃由于 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'));
}

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

PHP 5.3 + ,带闭包:

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

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

PHP 7引入了一个真正的 结合运算符结合运算符:

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

如果 ??之前的值不存在,或者 null是取 ??之后的值。

相对于上面提到的 ?:操作符的改进是,??还处理未定义的变量而不抛出 E_NOTICE

返回第一个非 NULL 值的函数:

  function coalesce(&...$args) { // ... as of PHP 5.6
foreach ($args as $arg) {
if (isset($arg)) return $arg;
}
}

相当于 PHP 7 + 中的 $var1 ?? $var2 ?? null

返回第一个非空值的函数:

  function coalesce(&...$args) {
foreach ($args as $arg) {
if (!empty($arg)) return $arg;
}
}

相当于 PHP 5.3 + 中的 (isset($var1) ? $var1 : null) ?: (isset($var2) ? $var2 : null) ?: null

上面将把“0.00”的数字字符串视为非空。通常来自 HTTPGET、 HTTPPOST、浏览器 cookie 或 MySQL 驱动程序,将浮点数或小数作为数字字符串传递。

返回第一个非未定义变量的函数,null,(bool) false,(int)0,(float)0.00,(string)”,(string)“0”,(string)“0.00”,(array)[] :

  function coalesce(&...$args) {
foreach ($args as $arg) {
if (!empty($arg) && (!is_numeric($arg) || (float)$arg!= 0)) return $arg;
}
}

用作:

$myvar = coalesce($var1, $var2, $var3, ...);