准备好的语句适用于 INSERT 但不适用于 SELECT

Posted

技术标签:

【中文标题】准备好的语句适用于 INSERT 但不适用于 SELECT【英文标题】:Prepared statement works for INSERT but not for SELECT 【发布时间】:2014-01-29 14:39:46 【问题描述】:

编辑:已解决,见下文但仍然不知道我做了什么让它工作:)

好的,我现在卡住了。我有表users:

ID int PRIMARY AUTO_INCREMENT
EMAIL varchar(60)
NICK varchar(60)
//...

如果我这样做:

<?php
$email = $_POST["mai"];
$nickname = $_POST["nck"];
$mysqli = new mysqli($db_host, $db_username, $db_password, $database);
$prepared_statement = "INSERT INTO users VALUES(?,?,?)";
if ($stmt = $mysqli->prepare($prepared_statement)) 
 $id = "";
 $stmt->bind_param("iss",$id,$email,$nickname); 
 $stmt->execute();

?>

它每次都有效。但是如果我对 select 做同样的事情:

<?php
 $previous_entries = new mysqli($db_host, $db_username, $db_password, $database);
 $check = $previous_entries->prepare("SELECT ID,NICK FROM users WHERE EMAIL=?;");
 $check->bind_param("s",$email);
 $check->execute();
 $check->bind_result($maybe_id,$maybe_got_something);

  while ($check->fetch())  //here was typo, but fixed now 
    if ($maybe_got_something==$nickname)
     echo "Hooray!";
    
   

?>

我从未见过“万岁!”

但是,如果我这样改:

$previous_entries = new mysqli($db_host, $db_username, $db_password, $database);
$prepared_statement = "SELECT ID,NICK FROM users WHERE EMAIL=";
$prepared_statement .=$email;
$result = $previous_entries->query($prepared_statement);
while ($row = $result->fetch_array())
  if ($row["NICK"]==$nickname)
     echo "Hooray!";
    

然后一切正常。

我在准备好的声明中犯了一些可怕的错误。但我真的真的找不到它......我在这里做错了什么?

编辑:更新了脚本以纠正错误的错字,并添加了这两行:

echo "maybeid: ".. $maybe_id;
echo "maybenick:". $maybe_got_something;

页面呼应:

  maybeid: maybenick: 

编辑:工作代码 在尝试调试它时,我得到了这个:

$previous_entries = new mysqli($db_host, $db_username, $db_password, $database);
$check = $previous_entries->prepare("SELECT ID,NICK FROM users WHERE EMAIL=?;");
$check->bind_param("s",$email);
$check->execute();
$check->bind_result($maybeid,$maybenick);
echo "maybeid: ".$maybeid;
echo "maybenick:". $maybenick;
// got rid of the if statement
  while ($check->fetch()) 
    echo "maybeid: ".$maybeid;
    echo "maybenick:". $maybenick;
    if ($maybenick==$nickname)

     echo "Hooray!";
    
   

但是......为什么它起作用了? :)

【问题讨论】:

为插入准备好的语句?为什么? 因为:第一,我有点担心用户会发送一些讨厌的东西,破坏我宝贵的数据库......第二:因为我想正确学习 php 和 mysqli,所以我觉得它可能是很好的练习 根据我的记忆,执行插入、删除和更新等查询,而查询功能用于选择。 尝试回显这个:'1: ' . $maybe_id . ' 2: ' . $maybe_got_something in while 对于你不工作的情况..你得到了什么? 查看编辑...没有帮助 sdo 远,做另一个更新 【参考方案1】:

准备好的查询是$check,但您在获取时使用的是$stmt

【讨论】:

是的。我也发现了这一点。现在更新脚本,如果有帮助会告诉你。【参考方案2】:

试试这个(使用从prepare返回的语句对象):

<?php
 $previous_entries = new mysqli($db_host, $db_username, $db_password, $database);
 $check = $previous_entries->prepare("SELECT ID,NICK FROM users WHERE EMAIL=?;");
 $check->bind_param("s",$email);
 $check->execute();
 $check->bind_result($maybe_id,$maybe_got_something);
 if($check->num_rows > 0)
  while ($check->fetch()) 
    if ($maybe_got_something==$nickname)
     echo "Hooray!";
    
   

?>

【讨论】:

在复制粘贴代码时解决了它,然后去掉了 if($check->num_rows > 0) 语句......但是。这里有什么变化?我瞎了…… 如果您准备 mysql 语句以使用 $previous_entries-&gt;prepare 执行,您将获得语句对象。这个对象你称之为$check。然后您必须使用此对象调用 bind_param、execute、bind_result、num_rows (get) 也用于 fetch。在您的原始代码中,您使用而不是 $chekc-&gt;fetch() 错误 $stmt-&gt;fetch() .. 但现在,我看到您已修复它:)【参考方案3】:

尝试将$stmt-&gt;fetch()换成这个$check-&gt;fetch()

您可能需要将 error_reporting 级别设置为类似

error_reporting = E_ALL & ~E_NOTICE

在你的开发环境中的 php.ini 中避免这种错误。

问候

【讨论】:

【参考方案4】:

您必须像这样更改您的代码:

...
$check = $previous_entries->prepare("SELECT ID,NICK FROM users WHERE EMAIL=:email;");
$check->bind_param(":email",$email);
...

【讨论】:

以上是关于准备好的语句适用于 INSERT 但不适用于 SELECT的主要内容,如果未能解决你的问题,请参考以下文章

导入语句适用于 PyCharm,但不适用于终端

MySQL 查询适用于 SELECT 但不适用于 UPDATE 语句

Javascript innerHTML 不适用于图像,但适用于文本?

IOS:应用内购买适用于 TestFlight,但不适用于发布

实体框架适用于本地服务器但不适用于远程

PHP:准备好的语句无法从单引号中逃脱