可能是PHP函数的未定义参数


Possibly-undefined argument to PHP function

在显示从数据库检索到的值时,可能存在也可能不存在的值,我的PHP代码有很多这样的内容:

if ( isset( $data['a'] ) )
    $a = number_format( $data['a'] );
else
    $a = '–';
if ( isset( $data['b'] ) )
    $b = number_format( $data['b'] );
else
    $b = '–';

(例如简化;$data['a']实际上类似于$data[$date][$part]['errors']。)后面是<td><?= $a ?></td><td><?= $b ?></td>

使用?:而不是if使代码在垂直方向上更紧凑但更丑陋。我想把这个放在一个函数中,这样我就可以使用

$a = someFunction( $data['a'] );
$b = someFunction( $data['b'] );

相反,这要好得多。但是,将一个未设置的变量作为函数参数会导致两个警告,一个警告未设置变量,另一个警告缺少函数参数。如果我制作明显的函数并用@调用它。。。

function formatIfAvail( $num, $dec = 0 )
{
    if ( isset( $num ) )
        return number_format( $num, $dec );
    return '–';
}
....
$a = @formatIfAvail( $data['a'] );

工作,但这似乎是一个糟糕的解决方案有没有办法在没有@的情况下做到这一点如果PHP有C++预处理器,我会使用#define来定义这样的东西。。。

#define NUMFMT( n, d )    ( isset( n ) ? number_format( n, d ) : '–' )
....
$a = NUMFMT( $data['a'], 0 );

但当然不是。

PHP在整个语言中发出警告。作为一种语言,它有很多怪癖和补丁,所以很难制作出好看的代码。

也就是说,检索像$data['a']$data[$date][$part]['errors']这样的东西,如果在值检索中出现问题,至少会生成警告。我说"至少"是因为它通常取决于ArrayAccess接口的实现(它定义了方括号运算符的用法),但在最常见的情况下,普通数组会触发通知。

因此,您可以在全球范围内关闭通知和警告:

error_reporting(E_ALL & ~(E_NOTICE | E_WARNING));

但也许您不想在全局范围内这样做,而只想在本地调用/代码块中这样做。这就是@操作符(语法丑陋)的作用所在。您可以在没有警告的情况下检索值:

$myValue = @$data['a'];
$myValue = @$data[$date][$part]['errors'];

而且你不会得到任何警告。

在正常情况下,您要评估:

$myValue = @$data['a'] or $anotherValue;

要做到这一点,在PHP中,您必须使用丑陋的elvis运算符(我同意您的观点):

$myValue = @$data['a'] ?: $anotherValue;

因为使用or||)执行此操作会给您一个布尔值。

此外,你还遇到了另一个问题:你不仅仅是想获得一个"或"默认值。正如我在代码中看到的,如果值存在,您将尝试转换该值,或者返回默认值PHP不以压缩的方式支持(我不知道有什么语言支持它)。

所以你被你所知道的卡住了。我更喜欢这个:

function someFunction( $num, $dec = 0 )
{
    return ($number !== null) ? number_format( $num, $dec ) : '-';
}
$myVal = someFunction(@data['a'] ?: null);