在php中,我应该在通常返回数组的方法中返回false、null或空数组吗


In php, should I return false, null, or an empty array in a method that would usually return an array?

我发现了一些对此的回应,但没有一个与PHP(这是一种非常弱的类型语言)有关:

关于PHP,在通常会返回数组但发生失败的方法中,返回false、null或空数组是否合适?

换句话说,如果另一个开发人员加入我的项目,他们会期望看到什么?

数组是事物的集合。空数组将表示"一切正常,只是集合中没有任何内容"。如果您确实想发出错误的信号,则应返回false。由于PHP是动态类型的,因此根据您的需要,可以很容易地严格或松散地检查返回值:

$result = getCollection();
if (!$result)           // $result was false or empty, either way nothing useful
if ($result === false)  // an actual error occurred
if ($result)            // we have an array with content

异常情况下,错误报告也有例外。这实际上取决于职能部门的责任和错误的严重程度。如果函数的角色允许响应"empty collection"answers"nope"相等,则上述情况可能会很好。但是,如果函数根据定义必须始终返回一个集合(即使它是空的),并且在某些情况下不能返回,那么抛出异常可能比返回false更合适。

我强烈反对返回混合类型的返回值。我认为这是一个很大的问题,所以我写了一篇关于不返回混合类型值的小文章。

若要回答您的问题,请返回一个空数组。下面你可以找到一个小例子,为什么返回其他值会导致问题:

// This kind of mixed-typed return value (boolean or string),
// can lead to unreliable code!
function precariousCheckEmail($input)
{
  if (filter_var($input, FILTER_VALIDATE_EMAIL))
    return true;
  else
    return 'E-Mail address is invalid.';
}
// All this checks will wrongly accept the email as valid!
$result = precariousCheckEmail('nonsense');
if ($result == true)
  print('OK'); // -> OK will be given out
if ($result)
  print('OK'); // -> OK will be given out
if ($result === false)
  print($result);
else
  print('OK'); // -> OK will be given out
if ($result == false)
  print($result);
else
  print('OK'); // -> OK will be given out

希望这有助于防止一些误解。

就我自己而言,我通常更喜欢返回一个空数组,因为如果函数总是返回一个数组,那么将其与PHP的数组函数和foreach一起使用是安全的(它们会接受空数组)。如果返回null或false,那么在将结果传递给数组函数之前,必须检查结果的类型。

如果你需要区分方法执行正确但没有找到任何结果的情况和方法中发生错误的情况,那么这就是异常的原因。在前一种情况下,返回空数组是安全的。在后者中,仅仅返回一个空数组不足以通知您发生了错误。但是,如果您返回的不是数组,那么您将不得不在调用代码中处理它。抛出异常可以在适当的错误处理程序中的其他位置处理错误,并可以将消息和代码附加到异常以描述失败发生的原因。

如果我们找不到任何感兴趣的东西,下面的伪代码将简单地返回一个空数组。然而,如果在处理我们返回的列表时出现问题,则会引发异常。

method getThings () {
    $things = array ();
    if (get_things_we_are_interested_in ()) {
        $things [] = something_else ();
    } 
    if (!empty ($things)) {
        if (!process_things ($things)) {
            throw new RuntimeExcpetion ('Things went wrong when I tried to process your things for the things!');
        }
    }
    return $things;
}

这是一个可能自20世纪60年代以来一直有效的现代答案。

在最早版本的PHP(在PHP4之前)中,一些糟糕的设计选择使许多PHP开发人员暴露在一直糟糕的约定中。幸运的是,PHP5的出现和消失帮助许多PHP开发人员走上了"正确的道路"。

PHP 7现在看到了经过PHP 5阶段的好处——它是目前运行速度最快的脚本语言之一。

  • 这使得PHP7成为目前速度最快、功能最强大的脚本语言之一成为可能

自PHP版本4以来,PHP核心开发人员付出了巨大的努力来逐步改进PHP语言。许多东西仍然存在,因为我们仍然希望具有一些向后兼容性。

错误时不要返回false

在出现错误的情况下,只有当函数的名称类似于isEverythingFine()时,才能返回FALSE

false一直是错误的错误返回值。在PHP文档中仍然可以看到它的原因,是因为它具有向后兼容性。

  1. 这将是不一致的。在函数应该返回布尔值truefalse的情况下,在出现错误时会返回什么?

  2. 如果你的函数应该返回布尔以外的东西,那么你就强迫自己编写代码来处理类型检查。由于许多人不进行类型检查,PHP操作码编译器也被迫编写进行类型检查的操作码你得到双重类型检查

可能返回null

大多数脚本语言都在其数据类型中为null值做出了有效的规定。理想情况下,您甚至不使用该值类型,但如果不能抛出异常,那么我更喜欢null。对于PHP中的所有数据类型,它都是一个有效的"值",即使它在PC内部不是一个有效值。

对于计算机/CPU来说,最理想的是整个值位于单个1、2、4或8字节的内存"单元"中。这些值大小对于所有本机值类型都是通用的。

如果允许值为null,则必须将其编码在单独的存储单元中,并且每当计算机需要将值传递给函数或返回值时,必须返回两个值。一个包含isNull,另一个用于值。

可能根据类型返回一个特殊值

这并不理想,因为

  • 如果函数应该返回一个整数,那么返回-1
  • 如果函数应该返回一个字符串

应该抛出异常

异常与大多数CPU的内部工作方式相匹配。他们有一个专用的内部标志来声明发生了异常事件。

它是高效的,即使不是,我们也有巨大的好处,在正常的非错误情况下没有很多额外的工作。

这取决于情况和错误的严重程度,但一个好的(经常被忽视的)选项是抛出异常:

<?php
function inverse($x) {
    if (!$x) {
        throw new Exception('Division by zero.');
    }
    else return 1/$x;
}
try {
    echo inverse(5) . "'n";
    echo inverse(0) . "'n";
} catch (Exception $e) {
    echo 'Caught exception: ',  $e->getMessage(), "'n";
}

这将确保你的功能不会悄无声息地失败,错误也不会被发现。

我假设方法的返回类型是数组,所以只有在执行顺利但没有找到结果的情况下,才应该返回空数组。

如果出现错误,您应该抛出一个异常。这应该是处理错误的首选方式。

如果真的有问题,那么你应该提出一个错误,否则如果不满足条件等,那么返回一个空白数组。

无论您喜欢哪种,尽管我建议使用空数组是有充分理由的。你不必先检查类型!

<?php
function return_empty_array() {
    return array();
}
$array = return_empty_array();
// there are no values, thus code within doesn't get executed
foreach($array as $key => $value) {
    echo $key . ' => ' . $value . PHP_EOL;
}
?>

在任何其他情况下,如果返回false或null,则foreach循环中会出现错误。

这是一个微小的差异,尽管在我看来是一个很大的差异。我不想检查我得到的值的类型,我想假设它是一个数组。如果没有结果,那么它就是一个空数组。

无论如何,就我而言,没有返回空值的"默认值"。原生PHP函数以其返回的不同值让我惊叹不已。有时为false,有时为null,有时为空对象。