从 mysqli 转换为准备好的语句

我试图将代码从 mysqli_* 语句转换为准备好的语句以防止 SQL 注入。以下代码是我正在尝试转换的代码(目前它可以正常工作):


$details = mysqli_query($linkDB,"SELECT * FROM ".PREFIX."Issues WHERE id='".$_POST['article']."' AND disabled='0' LIMIT 1");

$detail = mysqli_fetch_assoc($details);

这是我尝试转换为准备好的语句。任何使这更简洁的方法都将不胜感激(因为我将从 2 行代码变为多行):


$SQL = "SELECT * FROM ".PREFIX."Issues WHERE id='?' AND disabled='0' LIMIT 1";

$PRE = mysqli_stmt_init($linkDB);

//if (! $PRE = mysqli_prepare($linkDB, $SQL)) {   (alt attempt)

    if (! mysqli_stmt_prepare($PRE, $SQL)) {

        echo "<f><msg>ERROR: Could not prepare query: ".$SQL.", ".mysqli_error($linkDB)."</msg></f>";

    } else {

        mysqli_stmt_bind_param($PRE, "i", $test);

        $test = $_POST['article'];

        if (! mysqli_stmt_execute($PRE)) {

            echo "<f><msg>ERROR: Could not execute query: ".$SQL.", ".mysqli_error($linkDB)."</msg></f>";

        } else{

            $details = mysqli_stmt_get_result($PRE);

            $detail = mysqli_fetch_assoc($details);

            mysqli_stmt_close($PRE);

        }

}

上面的代码不会在 $detail 变量中返回/存储 db 值,以便稍后在脚本中进行处理。我试过注释掉 mysqli_stmt_close($PRE) 调用,但这没有区别。我感谢您的帮助!


catspeake
浏览 131回答 2
2回答

宝慕林4294392

代码中的主要错误是'?'查询中的拼写错误。如果?是在引号内,则不会将其视为占位符,而是将其视为文字值。使用 MySQLi 时,您应该启用 MySQLi 异常模式。如果这样做,则不再需要检查每个函数的结果。您还应该使用 OOP 风格,因为它不那么冗长,而且不太可能犯下愚蠢的错误。// put this line before you open the MySQLi connectionmysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);$stmt = $linkDB->prepare('SELECT * FROM '.PREFIX.'Issues WHERE id=? AND disabled=0 LIMIT 1');$stmt->bind_param('i', $_POST['article']);$stmt->execute();$detail = $stmt->get_result()->fetch_assoc();

米脂

如果您不是经验丰富的编码员,我会推荐 PDO。它是面向对象的,适合现代的 PHP 编码方式。在您的配置文件中,您输入:$db = new PDO('mysql:host=localhost;dbname=test', $user, $pass);还有你的脚本:$statement = $pdo->prepare('SELECT * FROM '.PREFIX.'Issues WHERE id = :id AND disabled = 0 LIMIT 1';$statement->execute(['id' => $_POST['article']);$result = $statement->fetch(PDO::FETCH_ASSOC);
打开App,查看更多内容
随时随地看视频慕课网APP