【问题标题】:My MySQL prepared statement won't work我的 MySQL 准备好的语句不起作用
【发布时间】:2017-10-17 20:01:01
【问题描述】:

我有一条不适合我的 MySQL 语句。我检查了代码的几个部分,但它一直返回 null 作为结果。我还尝试替换 WHERE enc_mail = AND enc_public_id=" to "WHERE 1" 以检查变量是否有问题,但事实并非如此。我也没有收到错误。

  $connect_db = mysqli_connect("myhost","my username","my password","my db");

    $mail_id = crypto(mysqli_real_escape_string($connect_db,htmlspecialchars($_GET['em'])),'e');
    $public_id = mysqli_real_escape_string($connect_db,htmlspecialchars($_GET['public']));
    $active_true = true;
    $check = $connect_db->prepare("SELECT active FROM enc_data WHERE enc_mail=? AND enc_pub_id=?");
    $check->bind_param("ss", $mail_id, $public_id);
    $active = $check->execute();

        if($active[0]=="" ){
        //It goes here once the code is run
    }

【问题讨论】:

  • 我没有看到你在这里检查错误。
  • 绝对没有理由同时使用real_escape_string() 参数化变量。参数化变量本身就足够了 :) 这也包括任何其他字符串清理,如果您使用参数化变量,则没有必要。摆脱所有这些肯定会有助于代码的可读性。
  • @garethpower 请重新添加错误记录部分,以便我们查看您如何检查错误
  • execute() 返回真/假
  • 一,秒我得到错误记录。看我让 $result = $stmt->execute() 在另一个页面上并且 $result['data'] 从那里正常工作

标签: php mysql mysqli prepared-statement


【解决方案1】:

您需要先申请bind_result,然后再申请fetch

当使用 @GrumpyCrouton 所说的准备好的语句时,绝对没有理由 escape_string

我建议您切换到 PDO,因为它更简单

【讨论】:

  • 嘿,如果您是 PDO 的粉丝,您应该查看class I wrote,如果您发现我可以做得更好,请告诉我
  • 1) 正如文档中提到的那样:php.net/manual/en/mysqli-stmt.fetch.php 2) 通常首先修改/加密/某个字符串然后/最后转义它,除非将其用作准备好的语句的参数 3 ) +1 为 PDO :-)
  • @clemens321 因为如果你在做任何其他事情之前转义字符串,它会改变修改/加密/什么的结果:P
  • 我现在去看看@GrumpyCrouton
  • +1 用于推荐无转义字符串和推荐 PDO,但对于它的价值,您可以使用没有 bind_result() 的 mysqli。您可以使用mysqli_stmt_get_result(),然后在结果上调用方法,如 fetch_assoc() 等。这使得使用 mysqli 更容易接受,但我还是更喜欢 PDO。
【解决方案2】:

我同意@Akintunde 的观点,即您不应该在查询参数上使用转义和 htmlspecialchars。使用查询参数时,转义是多余的。 htmlspecialchars 仅用于将内容输出到 HTML,而不是用于输入到 SQL。

对于 mysqli 查询,您不一定必须使用 bind_result()。您可以从准备好的语句中获取结果对象,然后在结果对象上使用 fetch 方法来获取连续的行。

我会这样写你的代码:

// makes mysqli throw exceptions if errors occur
mysqli_report(MYSQLI_REPORT_STRICT);

$connect_db = new mysqli("myhost", "my username", "my password", "my db");

$mail_id = $_GET['em'];
$public_id = $_GET['public'];
$active_true = true;
$sql = "SELECT active FROM enc_data WHERE enc_mail=? AND enc_pub_id=?";
$stmt = $connect_db->prepare($sql);
$stmt->bind_param("ss", $mail_id, $public_id);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
    if($row["active"]=="" ){
        //It goes here once the code is run
    }
}

但实际上我更喜欢使用 PDO 而不是 mysqli,所以我想这不是 真的我将如何编写 OP 的代码。 :-)

【讨论】:

  • 需要注意的是,get_result 不保证可用,可能会出现问题
  • @YourCommonSense,据我所知get_result() 需要 mysqlnd 驱动程序,然后它就可用了。还有其他原因无法使用吗?
  • 是的,就是这个原因。
  • 嗯,PHP 发行版默认为自 5.4.0 (2012-03-01) 以来的所有 mysql 扩展启用 mysqlnd 驱动程序。我认为依靠它可用是相当安全的。您可能会争辩说 PDO 或 mysqli 或 PHP 本身可能不“可用”。确实如此——就像任何软件一样,您必须先确保安装了这些软件包,然后才能使用它们!
  • 如果您说“有些人还没有升级到 PHP 5.4.0”,我会回答他们正在使用不受支持的软件。 PHP 5.4 和 PHP 5.5 都已结束其官方支持。
猜你喜欢
  • 1970-01-01
  • 2015-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-09
  • 1970-01-01
  • 2018-01-24
  • 2015-09-19
相关资源
最近更新 更多