【问题标题】:PHP Prepared Statement Result Array Not Finding Correct ValuePHP 准备好的语句结果数组未找到正确的值
【发布时间】:2013-07-19 03:45:42
【问题描述】:

下面的 PHP 在插入的情况下可以正常工作,但是对于绑定参数的选择查询,读取 json 的运气并不好。我现在创建的应用程序总是使用 if 语句评估行数返回 false。我觉得问题确实在于 mysqli_stmt_store_result($query) 的范围。用户的登录凭据在尝试登录时不起作用,即使它们是正确的。如果需要更多信息,请告诉我。数据库连接正常。

//parameter checking
$username = safe(stripslashes(trim($_POST['username'])));
$mypassword=hash('sha256', $salt.$_POST['password']);

//sanitize input parameters
function safe($value)
{
    global $db;

    $secureString = mysqli_real_escape_string($db, $value);

   return $secureString;
} 

//query check
$query= mysqli_prepare($db, "SELECT * FROM Users WHERE username =? AND password =? AND block_status < 1");
//$result=mysqli_query($db,$query);
mysqli_stmt_bind_param($query,'ss',$username,$mypassword);

mysqli_stmt_execute($query);

/* store result */
    mysqli_stmt_store_result($query);

$query2="UPDATE Users SET last_login=NOW() WHERE username ='" . $username . "' AND password = '" . $mypassword . "'";
$result2=mysqli_query($db,$query2);


//if match found, create an array of data and json_encode it
if(mysqli_stmt_num_rows($query)>0)
{


    $row=mysqli_fetch_array($query,MYSQLI_ASSOC);

    $response=array(

        'logged'=>true,
        'name'=>$row['name'],
        'email'=>$row['email']
    );

    echo json_encode($response);
}
else
{
    $response=array(

        'logged'=>false,
        'message'=>'Invalid credentials or your access has been revoked'
    );
    echo json_encode($response);
}

    /* free result */
    mysqli_stmt_free_result($query);

    /* close statement */
    mysqli_stmt_close($query);

    mysqli_close($db);

?>

【问题讨论】:

  • 如果使用参数绑定,则不需要使用mysqli_real_escape_string()
  • 谢谢,一旦我发现这个脚本错误,我会更新。
  • @Phil 出于某种非常奇怪的原因,OP 将准备好的语句用于第一个查询,但不用于第二个查询。

标签: php mysql json mysqli prepared-statement


【解决方案1】:

根据docs,你应该使用mysql_stmt_store_result()之前调用mysql_stmt_num_rows()

此外,您应该为您的UPDATE 查询使用参数绑定,但前提是您已确认成功登录。

我强烈推荐 PDO 而不是 MySQLi。 API 更简洁,更易于理解。下面是我的做法...

// assuming your user table has a primary key `id`
$stmt = $db->prepare('SELECT `id`, `name`, `email` FROM `Users` WHERE `password` = ? AND `username` = ? AND block_status < 1');
$stmt->execute(array($passwordHash, $username));
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if ($user !== false) {
    $response = array('logged' => true) + $row;

    $update = $db->prepare('UPDATE `Users` SET `last_login` = NOW() WHERE `id` = ?');
    $update->execute(array($row['id']));
} else {
    $response = array(
        'logged'  => false,
        'message' => 'Invalid credentials or your access has been revoked'
    );
}

$stmt->closeCursor();

header('Content-type: application/json');
echo json_encode($response);
exit;

【讨论】:

  • 我之前试过放,但后来我得到一个 json 错误。我是否应该为选择查询的参数绑定而烦恼?
  • @Klinetel 绝对。我总是会绑定用户输入。真的没有其他理智的选择。另外,您遇到了什么 JSON 错误?
  • 好的。我输入的应用程序说无法解析 JSON 字符串第 1 行......但是,当我将 mysqli_stmt_store_result 移动到 num 行 if 语句时,错误消失但 if 语句只会评估为 false。
  • @Klinetel 我已经使用bind_result()fetch() 更新了我的答案。您也许可以使用fetch_array(),但我对 MySQLi 不是很了解,所以不知道具体如何实现。我唯一的其他建议是使用 PDO,API much 更干净
  • 我认为不赞成票是由于伪代码示例。我已将其更新为真实的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-21
  • 1970-01-01
相关资源
最近更新 更多