准备好的声明; fetch()或fetch_all()? While Statement的问题

时间:2014-05-13 16:22:36

标签: php prepared-statement fetch

我正在尝试对我准备好的语句代码进行解密,但遇到了一些问题。使用下面的脚本时,我看到'test one'和'test two'在我的浏览器中回显,但没有'测试三'; my - > 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);

2 个答案:

答案 0 :(得分:1)

  

这种想法是否正确? fetch()为一个,fetch_all()为多个?

实际上,这是两个不同对象的两种不同方法。

  • fetch()属于mysqli语句对象,并使用丑陋的方法将查询结果分配给全局变量。 可以循环播放。 Loop是一个你可以多次获取一行的东西。因此,使用fetch()获取许多记录并不矛盾
  • fetch_all()属于mysqli结果对象,只是一个语法糖,在循环中为你运行fetch_assoc()。

答案 1 :(得分:-2)

这样的事情应该有效:

$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'];
    }
}