5

我从来不确定在 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
}

代码现在更好了,但它是否有点过于臃肿?我应该做这么多检查吗?

如果我不应该做这么多检查,你在哪里划定你应该检查和不应该检查的界限?

4

3 回答 3

4

这是动态类型语言的困境。这在很大程度上取决于 fetchCar() 函数在做什么。

我会采取的方法是假设 fetchCar 返回一个汽车数组或抛出异常。如果将此与良好的异常处理逻辑结合起来,您最终可以得到干净稳定的代码。

例如:

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 或抛出异常。但这当然并不总是可取的。

于 2013-07-11T13:08:45.233 回答
0

我宁愿把它全部变成一个可以在这些情况下重用的函数。

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

}
于 2013-07-11T13:10:04.183 回答
0

有些人没有注意到的一个问题。小心使用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
?>

PHPFiddle

将其与此进行比较:

$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()以及如何获取数据。如果您不能信任它(例如,它基于用户数据),那么您应该执行所有这些检查。如果不是,那真的没有意义。

于 2013-07-11T13:25:13.130 回答