什么应该在try块中以及在哪里返回我的值

时间:2017-03-18 14:09:59

标签: php exception-handling

在学习PHP时,我遇到了这个困境。例如,我有这个函数来检查数据库中是否存在客户端。

public function is_client( int $client_id ) {
    $query = "SELECT * FROM clients WHERE id='$client_id'";
    $res = DB::run($query)->fetch();
    if(empty($res)) {
        return false;
    }
    return true;
}

我想添加try / catch功能,以便能够捕获PDO错误,这就是它的照顾方式:

public function is_client( int $client_id ) {
    try {
        $query = "SELECT * FROM clients WHERE id='$client_id'";
        $res = DB::run($query)->fetch();
        if(empty($res)) {
            return false;
        }
        return true;
    }
    catch(PDOException $e) {
        return $e->getMessage();
    }
}

但我想知道,我应该在'试块'中加入什么?只有查询?我应该在'try block'或外面返回我的值吗?

我已经尝试了一点,所以我最终得到了以下内容:

public function is_client( int $client_id ) {
    try {
        $query = "SELECT * FROM clients WHERE id='$client_id'";
        $res = DB::run($query)->fetch();
    }
    catch(PDOException $e) {
        return $e->getMessage();
    }
    if(empty($res)) {
        return false;
    }
    return true;
}

请您解释一下这些例子之间有什么区别,哪些是正确的方法?

人们回答后更新

在阅读完答案后,我这样做了:

public function is_client( int $client_id ) {
    $query = "SELECT * FROM clients WHERE id='$client_id'";
    $res = DB::run($query)->fetch();
    if(empty($res)) {
        return false;
    }
    return true;
}// the function returns only boolean now


try {
    if(is_client(11) === true) {
        echo 'client';
    }
    else {
        echo 'client does not exist';
    }
}
catch(PDOException $e) {
    echo $e->getMessage();
}

3 个答案:

答案 0 :(得分:1)

在你的第一个例子中:

public function is_client( int $client_id ) {
    try {
        $query = "SELECT * FROM clients WHERE id='$client_id'";
        $res = DB::run($query)->fetch();
        if(empty($res)) {
            return false;
        }
        return true;
    }
    catch(PDOException $e) {
        return $e->getMessage();
    }
}

想象一下,在您的查询过程中会以某种方式抛出PDO异常(这会发生在$res = DB::run($query)->fetch();行),这会导致执行直接跳转到catch - 阻止和您的is_client函数(你通常希望返回一个布尔值)突然返回一个字符串。

因此,如果您正在使用is_client这样的功能:

if (is_client(123))
{
    echo "We have a valid client";
} else {
    echo "Client Invalid!";
}

实际上会打印valid-statement,因为非空字符串(您的异常错误消息)的计算结果为true。

正确的方法是不在is_client中捕获异常,而是在程序流程中稍后(例如在您使用is_client的块中)或返回有效函数中的/期望值(或抛出新的/自定义异常),例如:

public function is_client( int $client_id ) {
    try {
        $query = "SELECT * FROM clients WHERE id='$client_id'";
        $res = DB::run($query)->fetch();
        if(empty($res)) {
            return false;
        }
        return true;
    }
    catch(PDOException $e) {
        // Somehow write a log file with the error message $e->getMessage()

        return false; // Return false just to be save
    }
}

答案 1 :(得分:1)

的try / catch

摘要

将try / catch块放在调用函数的代码中,而不是函数本身。

详细

try / catch块将监视要抛出的异常,如果抛出 异常,则中断到块的 catch 部分。特别是在这种情况下,catch块正在监视PDOException的实例。

如果抛出PDOException,您肯定无法从查询中获得任何结果。在这种情况下,从函数返回异常并跳过返回不存在的结果更有意义。

推荐替代

正常的首选方法是设置函数将PDOException抛回到调用函数的代码中,并在那里的try / catch块中处理异常。这可以确保您的函数始终返回相同类型的值。

答案 2 :(得分:0)

我更喜欢第二个例子。如果DB::run($query)->fetch()引发异常,则不会以任何方式调用if(empty($res)) {