PHP和MYSQL的错误处理推荐方法

4

我正在尝试在我的PHP Web应用程序中捕获数据库(MYSQL)错误。目前,我看到有像mysqli_error()、mysqli_errno()这样的函数可以捕获最后发生的错误。然而,这仍然需要我在php代码中重复使用if/else语句来检查错误是否发生。您可以查看下面的代码以了解我的意思。是否有更好的方法来处理这个问题?还是我应该编写自己的代码来引发异常并在一个单一的地方捕获它们?此外,PDO是否会引发异常?谢谢。

function db_userexists($name, $pwd, &$dbErr)
{
    $bUserExists = false;
    $uid = 0;
    $dbErr = '';

    $db = new mysqli(SERVER, USER, PASSWORD, DB);

    if (!mysqli_connect_errno())
    {       
        $query = "select uid from user where uname = ? and pwd = ?";
        $stmt = $db->prepare($query);

        if ($stmt)
        {
            if ($stmt->bind_param("ss", $name, $pwd))
            {
                if ($stmt->bind_result($uid))
                {
                    if ($stmt->execute())
                    {
                        if ($stmt->fetch())
                        {
                            if ($uid)
                                $bUserExists = true;
                        }
                    }
                }
            }
            if (!$bUserExists)
                $dbErr = $db->error();

            $stmt->close();
        }       
        if (!$bUserExists)
            $dbErr = $db->error();      

        $db->close();
    }
    else
    {
        $dbErr = mysqli_connect_error();
    }

    return $bUserExists;
}

2
我认为异常处理是最好的方法。PDO 通过抛出异常来处理错误,你只需要在创建对象时设置 PDO::ERRORMODE_EXCEPTION 即可。 - Cfreak
@Cfreak:把你的评论变成答案。这是一个好建议。 - webbiedave
@Cfreak,我同意@Webbiedave的观点,请回答,因为我想点赞! - Josh
按照要求将其作为答案。 - Cfreak
4个回答

3
我已经创建了自己的代码来执行MySQL语句,并在它们失败时引发异常,包括不同失败原因的特定异常。其中最有帮助的之一是当冲突发生时,让我可以使用try..catch块并捕获DatabaseCollisionException,并将其与其他数据库异常区别对待。
我发现最容易做到这一点的方法是采用MVC设计模式,其中每个表都由一个PHP类(模型)表示,我可以仅分配成员变量并调用save方法保存到数据库,类似于:
try
{
   $user = new User();
   $user->username = 'bob';
   $user->setPassword($_POST['password'); // Could do some SHA1 functions or whatever
   $user->save
}
catch(DatabaseCollisionException $ex)
{
   displayMessage("Sorry, that username is in use");
}
catch(DatabaseException $ex)
{
   displayMessage("Sorry, a database error occured: ".$ex->message());
}
catch(Exception $ex)
{
   displayMessage("Sorry, an error occured: ".$ex->message());
}

如果想了解更多类似的设计模式,请参考以下链接:

当然,这不是唯一的答案,只是一些你可能会发现有用的想法。


我是DatabaseCollisionException的粉丝。 - Justin Johnson

1

我认为异常处理是最好的方法。PDO确实会抛出异常,你只需要在创建对象时设置PDO::ERRORMODE_EXCEPTION即可。


0
您可以按照以下方式重写它: $bUserExists = false; $uid = false;
if (!mysqli_connect_errno())
    {       
        if($stmt = $db->prepare("select uid from user where uname = ? and pwd = ?")
                   ->bind_param("ss", $name, $pwd))
        {
           $stmt->execute();

           $stmt->bind_result($uid);

           $stmt->fetch();

           $stmt->close();
        }

        if ($uid)
           $bUserExists = true;

        $db->close();
    }
    else
    {
        $dbErr = mysqli_connect_error();
    }

0
这仍然需要我使用重复的if / else语句检查错误的发生。
怎么样?您不需要检查每个可能的错误。 我只会对返回的值进行最终检查,仅此而已。 您是出于什么目的使用这些嵌套条件的?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接