【问题标题】:Error handling with mysqli [duplicate]使用 mysqli 处理错误 [重复]
【发布时间】:2016-09-08 22:27:06
【问题描述】:

我正在重构我的一些旧代码,并正在创建一个带有 INSERT 函数的数据库类。出于测试目的,我将它留在了课堂之外,并希望让它处理错误。

我想删除 php 错误并返回我自己的错误。目前我有以下内容,并且在重复键上插入时可以正常工作,但是当我测试从 bind_param 中删除类型参数时,出现以下错误:

警告:mysqli_stmt::bind_param():第 17 行 /home/matt500b/csgoberry/public/catch.php 中的类型无效或未指定类型

执行语句失败:没有为准备好的语句中的参数提供数据

如何删除警告问题并仅保留返回的字符串?或者对于生产服务器来说,这种操作的最佳方法是什么。

关于 mysqli 查询,我还可以模拟哪些其他错误?

function INSERT($link, $sql, $args=null) {
    
    if ($stmt = $link->prepare($sql)) {
        for($i=0; $i<count($args); $i++) {
            $stmt->bind_param($args[$i]["type"], $args[$i]["value"]); 
        }
        if(!$stmt->execute()) {
            return 'Executing the statement failed: ' . htmlspecialchars($stmt->error);
            exit();
        }
    }
    else {
        return 'Preparing the statement failed: ' . htmlspecialchars($link->error);
        exit();
    }
    
    return 'Finished';
}

$query = "INSERT INTO insertTest (`value`) VALUES (?)";
$queryArgs[] = array("type"=>"", "value"=>"test1");
echo INSERT($link, $query, $queryArgs);

【问题讨论】:

  • 我正在模拟错误以正确捕获和显示所有错误。我故意将"type"=&gt;"" 留空。因此,投票不会重复作为关于如何处理此类错误的问题
  • 在执行过程中尝试了 try/catch,但是我的自定义错误没有显示,只有 php 警告错误显示
  • Try/catch 是针对异常而不是 php 警告或错误。不要认为你可以使用 MySqli 类来实现这一点,但你当然可以使用 PDO 类来实现。
  • 生产服务器通常会关闭错误报告,因此您不会在那里看到警告。如果你同意的话。

标签: php mysqli


【解决方案1】:

坦率地说,错误处理的整个想法是错误的。返回错误消息的函数是致命的罪过。一个函数应该返回与其目的相关的东西。例如,一个插入函数应该返回一条语句,让您可以从中使用例如affected_rows 变量。

虽然必须以完全不同的方式处理错误。

另外,你使用mysqli的方式是错误的,这段代码无论如何也不会工作。

假设您出于某种原因进行重构,并且可以使用 已经稍微过时 PHP 5.6 版本,这里是运行任何查询的函数,而不仅仅是 INSERT:

function query($link, $query, $params = NULL, $types = NULL)
{
    if (!$params)
    {
        return $link->query($query);
    }
    $statement = $link->prepare($select);
    $types = $types ?: str_repeat('s', count($params));
    $statement->bind_param($types, ...$params);
    $statement->execute();
    return $statement;
}

这就是它的使用方式

$query = "INSERT INTO insertTest (`value`) VALUES (?)";
query($link, $query, ['test1']);

或者,如果你想设置类型,

$query = "INSERT INTO insertTest (`value`) VALUES (?)";
query($link, $query, ['test1'], "s");

现在,进入令人兴奋的错误报告主题。只需按照this answer 中的说明进行操作即可。

简而言之:mysqli 已经可以报告它的错误,并且比你的代码做得更好。所以别管它,让 PHP 处理所有错误。

【讨论】:

    【解决方案2】:

    如果要禁止警告,可以将@运算符放在导致警告的函数或方法调用前面:

    @$stmt->bind_param($args[$i]["type"], $args[$i]["value"]);
    

    不过,通常情况下,您应该检查传入函数的无效数据将数据传递给较低级别​​的函数,这意味着不需要@,因为不会调用较低级别的函数在错误的情况下。

    【讨论】:

    • 无需手动测试输入数据,因为 mysqli 已经拥有所有检查程序,您可以设计更多。所以实际上应该让 mysqli 检查并告诉你错误是什么。此外,@ 是邪恶的。没有任何借口。
    • 是的,@ 是邪恶的。我正在回答这个问题(OP 想要禁止警告)并解释说自己进行错误检查比使用 @ 更好。
    猜你喜欢
    • 2012-03-10
    • 2013-01-14
    • 2011-02-25
    • 2019-07-29
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    • 2015-02-18
    • 2014-11-18
    相关资源
    最近更新 更多