Php 准备好的声明;fetch()或fetch_all()?发出While语句

Php 准备好的声明;fetch()或fetch_all()?发出While语句,php,prepared-statement,fetch,Php,Prepared Statement,Fetch,我正在尝试对我准备好的语句代码进行除虫,但遇到了一些问题。当使用下面的脚本时,我看到“测试一”和“测试二”在我的浏览器中回响,但没有“测试三”;我的->fetch()语句似乎不起作用。没有错误 if (empty($login_errors)) { // OK to proceed! echo 'test one'; $pas = get_password_hash($p); $loginQuery = $dbc->prepare("SELECT id, username, type

我正在尝试对我准备好的语句代码进行除虫,但遇到了一些问题。当使用下面的脚本时,我看到“测试一”和“测试二”在我的浏览器中回响,但没有“测试三”;我的->fetch()语句似乎不起作用。没有错误

if (empty($login_errors)) { // OK to proceed!

echo 'test one';

$pas = get_password_hash($p);
$loginQuery = $dbc->prepare("SELECT id, username, type FROM user WHERE (email=? AND pass=?)");
$loginQuery->bind_param('ss',$e,$pas);
$loginQuery->execute();
$loginQuery->bind_result($id,$username,$type);

echo 'test two';

while($loginQuery->fetch()){

echo 'test three';

$idRow = $id;
$usernameRow = $username;

$_SESSION['user_id'] = $idRow[0];
$_SESSION['username'] = $usernameRow[0];
} 
echo 'test four';
}
我的第一个想法是,当只选择一个字段(一个绑定结果)时,使用
->fetch()。我尝试使用
while($loginQuery->fetch_all()){
,因为我有三个(
$loginQuery->bind_result($id,$username,$type);
),但这会返回HTTP 500错误。这种想法正确吗?一个是fetch(),多个是fetch_all()

为什么两个回迁都不起作用?你能看到我的代码有什么问题吗

将显示“test four”。这表明查询未返回任何数据。这令人困惑,因为在此准备好的语句之前,我使用了连接,下面的操作没有任何问题:

$q = "SELECT id, username, type, IF(date_expires >= NOW(), true, false) FROM user WHERE (email='$e' AND pass='"  .  get_password_hash($p) .  "')";      
$r = mysqli_query ($dbc, $q);

像这样的方法应该会奏效:

$loginQuery = $dbc->stmt_init();
$loginQuery = $loginQuery->prepare("SELECT id, username, type FROM user WHERE LOWER(email) = LOWER(?) AND pass = ?");
$loginQuery->bind_param('ss',$e,$pas);
$loginQuery->execute();
$results = $loginQuery->get_result();
if($results->num_rows > 0)
{
    $row = $results->fetch_assoc();
    $user_name = $row['username'];
    $user_id = $row['id']; 


    $_SESSION['user_id'] = $user_id;
    $_SESSION['username'] = $user_name;
}
else
{
    echo "no rows returned, bad username and password.";
}
假设$dbc是mysqli对象,在准备之前还需要调用
stmt_init()

$loginQuery = $dbc->stmt_init();
还使用LOWER()使查询对电子邮件不区分大小写,您应该在登录和注册时执行此操作。这样,就不会有人在email@email.com,然后其他人向EMAIL@email.com.您应该检查他们注册的电子邮件是否与数据库中的电子邮件不匹配,并且在检查时使用mysql LOWER()函数进行比较

上面的代码将使您获得结果集中的第一行。如果您需要获得所有行,您的思路是正确的。但您必须执行以下操作:

$usersQuery = $dbc->prepare("SELECT id, username, type FROM user");
$usersQuery->execute();
$results = $usersQuery->get_result();   
if($results->num_rows > 0)
{
    while($row = $results->fetch_assoc())
    {
        $user_id = $row['id'];
        $user_name = $row['username'];
        $user_type = $row['type'];
    }
}
这种想法正确吗?一个取(),多个取_all()

这实际上是两种不同的方法来处理两个不同的对象

  • fetch()属于mysqli语句对象,使用难看的方法将查询结果分配给全局变量。可以在循环中运行。循环是一种可以多次获取一行的操作。因此,使用fetch()获取多条记录不会有任何矛盾
  • fetch_all()属于mysqli结果对象,只是一个语法糖,在循环中为您运行fetch_assoc()

您的语法看起来是正确的。为什么不在循环后添加
echo'test four';
,这将表明您的查询没有返回任何结果?如果您没有看到额外的测试,那么这意味着您的脚本正在悄无声息地消亡,您需要打开/打开
错误报告
。此外,您还应该检查至少lea的返回值st
prepare()
execute()
,它们都可以在不停止脚本执行的情况下失败。谢谢。将显示“test four”并提示SQL查询没有结果。这令人困惑,因为我最初的未准备语句(如下)工作正常。我已修改了问题,以包括更新的工作。