如何在PHP中处理类型检查样板


How to handle type checking boilerplate in PHP

我正在编写一个处理数组的实用函数。为了避免复杂性,我们假设它是一个简单的句柄,可以将简写数组插入到函数中:

function array_insert($original_arr,$key,$val){
    $original_arr[$key]=$val;
    return $original_arr;
}

用例为例如

validate_input(array_insert($_GET,'extra-key','val'));

现在假设$_GET可能不是数组。或者说我们正在从外部调用中获取输入;检查第一个参数是数组的责任在哪里?

如果这形成了一个复杂的处理堆栈的开始,我们可以做:

if (is_array($our_data)){
    do_something($our_data);
    do_something_else(array_insert($our_data,'key','val'));
}

不过,这并不能让调用作用域知道do_something没有发生。所以我们可以做:

if (!is_array($our_data)){
    throw new Exception('not an array');
}

现在,任何使用我们方法的东西都需要准备好捕捉它,根据我们是否真的关心结果,我们可能需要在我们的方法中捕捉它。

我们可以简单地退出效用函数并返回false,其他东西可以检查:

function array_insert($original_arr,$key,$val){
    if (!is_array($our_data)){
        return []; // which is empty but expected, or return false.. or null...
    }
}

然后是最低级别:

function array_insert(Array $original_arr)

如果没有传递数组,这将触发PHP级别的异常。

所以问题是;对于一个实用函数,我们对用例承担多少责任?我们会用TypeHint引起语言异常吗?我们会无声地失败吗?我们不会费心检查并让最终用户弄清楚吗?

更新

首先,人们注意到这是主观的——我同意,尽管可能有一个既定的最佳实践,例如PHP世界中的认证计划或大公司推荐的最佳实践。

第二个问题(由第一个答案提示)是,对于这类问题,是否有一个已建立的Exception类/类名?

正如评论中已经提到的,这完全是主观的,但就个人而言:

  • 我总是对对象和数组使用类型提示。

  • 对于在基元类型上操作的函数,只有当某些值无效并且可能不明显时,我才会基于该值抛出InvalidArgumentException。例如,计算数字平方根的函数在传递负数时可能引发异常。

  • 在所有其他情况下,我使用有意义的函数/参数名称,并假设如果有人决定将非数字字符串或数组传递给定义为doStuffWithNumbers($num1, $num2),如果结果不好,那是他的责任。