【问题标题】:What is the procedural mysqli way of preparing SQL statements?准备SQL语句的程序mysqli方式是什么?
【发布时间】:2016-04-18 01:46:35
【问题描述】:

我的代码中有一个 SQL 查询,我想将其转换为准备好的语句以阻止 SQL 注入等漏洞。所以这就是我想要转换的:

<?php
$query = "SELECT * from `wp_posts` WHERE ID=$pid ";
$result = mysqli_query($link, $query);
    //$id=$row['Gallery_Id'];

    while($row = mysqli_fetch_array($result)){
        ?>
    <h2 align="center"> <?php echo $row['post_title']; ?> </h2><br>
    <div class="paracenter">

        <p id="cont"><?php echo $row['post_content']; ?></p>
        <hr color="black" width="10%">

    </div>
<?php } ?>

这是我尝试过的,但它不起作用。

$query = "SELECT * from `wp_posts` WHERE ID=? ";
    $stmt = mysqli_prepare($link, $query);
    if($stmt){
        mysqli_stmt_bind_param($stmt, "i", $pid);
        mysqli_stmt_bind_result($stmt, $dbpid);
        mysqli_stmt_execute($stmt);
        mysqli_stmt_fetch($stmt);
    }
    $result = mysqli_query($link, $query);
    //$id=$row['Gallery_Id'];

    while($row = mysqli_stmt_fetch($result)){
        ?>


    <h2 align="center"> <?php echo $row['post_title']; ?> </h2><br>
    <div class="paracenter">

        <p id="cont"><?php echo $row['post_content']; ?></p>
        <hr color="black" width="10%">

    </div>
    <?php } ?>

网上几乎所有的例子都没有使用我使用的程序方法。我该如何纠正这个问题?

【问题讨论】:

  • 手册有OOP和程序风格。 php.net/manual/en/mysqli-stmt.bind-param.php目前发生了什么
  • 是的,那里的例子只是使用定义的变量来输出。没有提到当查询为SELECT *@chris85 时如何获取值
  • php.net/manual/en/mysqli.error.php 并将其应用于您的查询。
  • 你搞砸了,你在混合*i_query()和准备好的语句api
  • @Ghost,你能告诉我如何纠正它吗?

标签: php stored-procedures mysqli prepared-statement procedural


【解决方案1】:

为了保护您的查询免受注入攻击,您有两种选择。第一个超级简单,与准备好的语句一样安全。

  1. $pid 转换为整数。

    $query = "SELECT post_title, post_content FROM wp_posts WHERE ID = " . (int)$pid;
    

    安全并完成。

  2. 如何编写带有结果绑定的预处理语句...(我不使用过程式 mysqli 语法)

    if (!$stmt = $link->prepare("SELECT post_title, post_content FROM wp_posts WHERE ID = ?")) {
        echo "Syntax Error @ Prepare"; // $link->error; <-- never show actual error details to public
    
    } elseif (!$stmt->bind_param("i", $pid) || !$stmt->execute() || !$stmt->bind_result($title, $content)) {
        echo "Syntax Error @ ParamBind | Execute | ResultBind"; // $stmt->error; <-- never show actual error details to public
    } else {
        while ($stmt->fetch()) {
            echo "<div>";
                echo "<h2 align=\"cente\">$title</h2><br>";
                echo "<div class=\"paracenter\">";
                echo "<p id=\"cont\">$content</p>";
                echo "<hr color=\"black\" width=\"10%\">";
            echo "</div> ";
        }
    }
    

一些附加说明。

  • 如果您不打算使用结果绑定,您应该使用mysqli_fetch_assoc() 而不是mysqli_fetch_array()mysqli_fetch_array() 将生成一个包含索引元素和关联键元素的臃肿结果集(您实际需要的两倍)。
  • 使用bind_result()时,需要将SELECT子句中的*替换为要提取的列。
  • 我的第一个elseif() 表达式包含对$stmt 的三个单独的调用和检查。只要其中任何一个调用返回虚假/错误响应,条件表达式就会短路,并且表达式中的其余调用永远不会执行。
  • 如果采用我的面向对象的 mysqli 风格,请务必将您的数据库连接语法也与面向对象对齐。

【讨论】:

    猜你喜欢
    • 2013-10-22
    • 2011-07-09
    • 1970-01-01
    • 2012-12-01
    • 2013-11-19
    • 2011-08-02
    • 2016-12-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多