很多编程语言都有一个合并函数(返回第一个非 NULL 值 例子) ,遗憾的是,2009年的 PHP 没有。
在 PHP 本身得到一个聚合函数之前,如何在 PHP 中实现一个聚合函数?
“ 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函数通常所做的。例如:
coalesce
echo 42 === coalesce(null, 0, 42) ? 'Oops' : 'Hooray';
哎呀
为了克服这个问题,需要第二个参数和函数定义。可召唤的函数负责告诉 array_filter是否向结果数组添加当前数组值:
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,那就太好了,但是没有这样的运气。
isset
'isset'
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是取 ??之后的值。
??
null
相对于上面提到的 ?:操作符的改进是,??还处理未定义的变量而不抛出 E_NOTICE。
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。
$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。
(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, ...);