您应该进行多少变量检查

  • 本文关键字:变量 多少 php variables
  • 更新时间 :
  • 英文 :


我一直不确定在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
}

最新更新