【问题标题】:PHP MySQLi Prepare Statement Failing to return rowsPHP MySQLi准备语句无法返回行
【发布时间】:2012-08-12 06:52:45
【问题描述】:

我一直在用 PHP 将很多旧的 MySQL 东西转换为 MySQLi,但在以下代码中遇到了问题:

### FETCH INCLUDES ###
$player=$_POST['player'];
$password=md5($_POST['password']);
#### DB CONNECTION ####
if(!$mysqli=new mysqli(DBHOST,DBUSER,DBPWD,DBNAME)) {$err=$mysqli->error; print($err); }
$sql="SELECT * FROM accounts WHERE name='?' AND passkey='?'";
if($stmt=$mysqli->prepare($sql)) {
    //$stmt->bind_param('ss',$player,$password);
    $stmt->execute();
    $stmt->store_result();
    if($stmt->num_rows==1) {
        $account=$stmt->fetch_assoc();
        // purely for debugging
        print_r($account);
        if($_SESSION['account']=$account) $account=true;
    } else {
        echo "Failed. Row count: ";
        print($stmt->num_rows);
        echo "<br />";
        $query=str_replace('?','%s',$sql);
        printf($query,$player,$password);
        $account=false;
    }
    $stmt->close();
} else {
    $err=$mysqli->error;
    print($err);
}

我已将故障范围缩小到查询本身。我返回 0 行,没有错误,所以我想我会输出查询(我要去那里的 str_replace 东西),我可以使用查询从数据库中返回一行,使用来自 PHPMyAdmin 的相同查询

我哪里错了?

编辑

我尝试将查询更改为没有绑定参数的基本查询 - “SELECT * FROM table” 仍然没有返回任何行。所以这不是查询本身,而是我准备、执行情况的顺序/格式

第二次编辑:我已将 $stmt->store_result() 添加到代码中,但仍返回 0 行数。

第三次编辑: 我调查了看起来不错的连接和用户设置。我可以通过控制台使用相同的用户和密码连接到数据库,并且数据库名称相同。我真的很难过这个:(

【问题讨论】:

  • 不是答案,但请不要使用 md5 对密码进行哈希处理。它完全坏掉了。查看 bcrypt,您可能还想了解加盐密码。
  • 您确定有匹配的行吗?您是否尝试过 echoing 语句和值并手动运行查询?
  • 是的,这就是 printf 的用途,输出它正在运行的确切查询并返回行。我现在正在尝试其他一些事情。我认为这可能与我缺少的某种准备/执行步骤有关
  • 如果不要求所有人重置密码,我目前无法更改 md5。在 MySQLi 格式的一切都结束后,我可能会这样做
  • @elzaer - 你检查过$stmt-&gt;num_rows 实际上返回 0 吗?

标签: php mysqli mysql-num-rows prepare


【解决方案1】:

$stmt-&gt;execute(); 之后添加一个$stmt-&gt;store_result();,因为它似乎必须在$stmt-&gt;num_rows 之前调用一次......至少他们在示例中这样做(参见http://php.net/manual/en/mysqli-stmt.store-result.php)。它们意味着“num_rows”文档中的依赖关系。

其他想法:你检查if($stmt-&gt;num_rows==1) {,你确定num_rows 是0 吗?我不知道您的“帐户”表的数据库结构。 “名称”是主键(或至少是唯一索引)吗?如果不是,则可能有多个匹配的列。这只是一个快速的想法可能是什么问题,并导致您在源代码中寻找问题的时间。虽然问题出在其他地方。

【讨论】:

  • 添加了 store_result() 并且仍然得到相同的结果。我编辑了代码,如您所见,我运行调试以显示返回的行数,无论我运行什么查询,它都是 0。我尝试了“SELECT * FROM accounts”,它也返回 0 行数,这让我认为数据库选择或类似的东西可能存在问题。不过这很奇怪,当我尝试将其更改为不存在的东西时出现连接错误,所以我真的很困惑。
  • 你能以某种方式在服务器上执行调试输出的查询吗(例如,通过 mysql 客户端或 phpmyAdmin?)。只是想看看,天气这会给出结果行...请注意,您当然需要在字符串周围添加“...”。
  • 是的,这就是我在 printf($query...) 行中添加的原因,因此我很容易在服务器端运行它。正如我所说,这不是查询。当我在服务器上运行它时,查询会返回我想要的。不管我在那里输入什么查询,它总是返回 0 行数
  • 我很确定这与我服务器上的用户/连接设置有关。当我输出 $mysqli->host_info 时,它似乎连接正常,但我不知道用户和 Linux 上没有什么
  • 是的……就是这样!看看我的另一个答案。如果连接建立成功,您需要修复您的检查;-) 如果正确,您至少会收到一条错误消息。当我在服务器上尝试错误的凭据时,您的代码只是跳过了错误输出。
【解决方案2】:

好的,我确实检查了您的代码。首先,您应该在连接时修复错误处理。不要检查“$mysqli”是否为真,而是像这样检查 mysqli_connect_errno():

$mysqli=new mysqli(DBHOST,DBUSER,DBPWD,DBNAME);
if (mysqli_connect_errno()) {
  printf("Connect failed: %s\n", mysqli_connect_error());
  exit();
}

在我的服务器上,您的代码使用正确的凭据(例如,需要替换 DBHOST、DBUSER、DBPWD、DBNAME)。

并且声明$account=$stmt-&gt;fetch_assoc(); 不起作用。 $stmt 对象中没有 fetch_assoc() 函数。 fetch_assoc() 用于通过使用普通查询(不是准备好的语句)获得的 mysqli::result 对象。您需要使用 $stmt->bind_result();然后 $stmt->fetch();此外,您应该在查询中放置所有列名的列表而不是“*”,这定义了字段顺序...

【讨论】:

  • 那个 fetch_assoc 确实需要修复,但至少结果是返回,它很容易从那里调整和成型!
  • 我可以使用 bind_result 将一个包含 3 列的数组绑定到一个 cariable 上吗?因此,如果我在查询中选择我想要的列,并将它们全部绑定到一个变量,它会变成一个关联数组吗?
  • 否,但您可以尝试绑定到多个子元素...到 $data["x"] 和 $data["y"] 和 $data["z"] 等等。 .. mysqli 在这里不是很灵活。也许“PDO”更好:见de2.php.net/manual/de/pdostatement.fetchobject.phpde2.php.net/manual/de/book.pdo.php;到目前为止还没有尝试过......只是查看了文档。
【解决方案3】:

我得到它的工作,我最终需要 $stmt->store_result();

但我也注意到我在 ? 周围添加了单引号在导致问题的准备语句中。

取出这些并离开 store_result 方法后,它就可以工作了!

【讨论】:

    猜你喜欢
    • 2012-01-31
    • 1970-01-01
    • 2015-03-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-08
    • 2012-05-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多