我一直不确定在PHP中要做多少变量检查。例如,以下面的一段代码为例。在分配变量或将其传递给函数之前,我不会检查任何变量,以查看它们是否包含我期望的
$carId = '12';
$aCar = fetchCar($carId);
$make = $aCar['make'];
$model = $aCar['model'];
$yearMade = $aCar['year'];
$age = calcAge($yearMade);
现在,如果我添加一些检查
$carId = '12';
if(is_numeric($carId))
{
$aCar = fetchCar($carId);
if(isset($aCar['make']) && is_string($aCar['make']))
{
$make = $aCar['make'];
}
else
{
//Report error
}
if(isset($aCar['model']) && is_string($aCar['model']))
{
$model = $aCar['model'];
}
else
{
//Report error
}
if(isset($aCar['year']) && is_numeric($aCar['year']))
{
$yearMade = $aCar['year'];
$age = calcAge($yearMade);
}
else
{
//Report error
}
}
else
{
//Report errors
}
代码现在更好了,但它是否有点过多和过于臃肿?我应该做这么多检查吗?
如果我不应该做这么多检查,你在哪里划分你应该检查和不应该检查的界限?
这是动态类型语言的困境。这在很大程度上取决于fetchCar()函数的作用。
我会采取的方法是假设fetchCar正在返回一个car数组或抛出异常。如果将其与良好的异常处理逻辑相结合,最终可以得到干净稳定的代码。
例如:
function fetchCar($id) {
$car = queryDatabaseSomehow();
if (empty($car)) {
throw new ExceptionNotFound();
}
//eventually you can put your type checking here?
if (!isset($car['x']) || !is_string($car['x'])) {
throw new ExceptionDb();
}
}
echo fetchCar(3)['make'];
此外,如果你想做这件事并完全OOP,Car应该成为一个以品牌、型号和年份为成员的类。fetchCar()将返回Car或抛出Exception。当然,这并不总是可取的。
有些人没有注意到的一个问题。小心使用is_string
:
<?php
$var = "test";
$var['something'] = 2;
if(is_string($var['something'])) {
echo "Hello world!"; // Will echo this because $var is a string!
} else {
echo "Hello hell!";
}
echo "<br/>";
echo $var['something']; // returns 2
?>
PHPIddle。
将其与以下内容进行比较:
$var = array('something' => 2);
if(is_string($var['something'])) {
echo "Hello world!"; // $var is now an array
} else if (is_numeric($var['something'])) {
echo "Hello hell!"; // Will echo this because $var is string!
}
echo "<br/>";
echo $var['something'];
您需要检查$var
是否是一个数组,因为它可能会给您带来意外的结果。在第一个示例中,isset($var['something'])
将返回true。
为了回答你的问题,我不认为这些支票太多。这实际上取决于fetchCar()
做什么以及它如何获得数据。如果你不能信任它(比如说,它是基于用户数据),那么你应该执行所有这些检查。如果没有,那就没有意义了。
我宁愿把它全部变成一个可以在这些情况下重用的函数。
function check_keys($arr_check, $arr_cond) {
$boo_success = TRUE;
foreach(array_keys($arr_cond) as $h)
if (in_array($arr_cond[$h], array('is_string', 'is_numeric'))) {
if ( ! isset($arr_check[$h]) or ! ($arr_cond[$h]($arr_check[$h]))) {
$boo_success = FALSE;
echo "The key {$h} is missing!";
// If run through a class, $this->errors[] = 'error message';
}
} else {
$boo_success = FALSE;
echo 'Invalid function';
}
return $boo_success;
}
$arr_keys = array('make' => 'is_string',
'model' => 'is_string',
'year' => 'is_numeric');
if (check_keys($aCar, $arr_keys)) {
// Run successful stuff
}