我通过使用echo语句替换IF中的所有语句并检查其工作正常来检查我的代码。
if($rows==1){
echo "Record exists in DB";
}
我不知道为什么$result = mysqli_stmt_get_result($stmt);
返回false并且我收到错误
警告:mysqli_fetch_array()要求参数1为mysqli_result,布线在第57行的E:\ xampp \ htdocs \ _jq \ login_system_sql_injection_proof \ loginprocess.php中给出
我在互联网上搜索解决方案却浪费了一天多的时间,却没有找到任何解决方案。如果有人帮助我,我将非常感激。我期望以程序方式解决方案。在此先感谢
<?php require("dbconnect.php"); ?>
<?php
$uname = $pass = "";
if($_SERVER['REQUEST_METHOD']=='POST'){
if(empty($_POST['uname'])){
header("location:loginform.php?error=".urlencode("Please enter your username"));
exit();
//$unameErr = "Please enter username";
}
else{
$uname = test_input($_POST["uname"]);
$uexp = "/^[a-zA-Z]*$/";
if(!preg_match($uexp,$uname)){
header("location:loginform.php?error=".urlencode("username should contaion only Alphabetic chars"));
exit();
//$unameErr = "only alphabets are allowed";
}
else $uname = mysqli_real_escape_string($con,$uname);
}
if(empty($_POST['pass'])){
header("location:loginform.php?error=".urlencode("Please enter your password"));
exit();
//$passErr = "Please enter password";
}
else{
$pass = test_input($_POST["pass"]);
$pass = mysqli_real_escape_string($con,$pass);
}
}
function test_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
?>
<?php
$query = "SELECT *FROM user WHERE user.username = ? AND user.password = ?";
$stmt = mysqli_prepare($con,$query);
if($stmt){
mysqli_stmt_bind_param($stmt,'ss',$uname,$pass);
$run = mysqli_stmt_execute($stmt);
if($run){
mysqli_stmt_store_result($stmt);
$rows = mysqli_stmt_num_rows($stmt);
if($rows==1){
$result = mysqli_stmt_get_result($stmt);
$row = mysqli_fetch_array($result, MYSQLI_ASSOC);
echo $row['username'];
//session_start();
//$_SESSION['uid'] = $row['username'];
//header('location:welcome.php');
}
else{
header('location:loginform.php?error="Invalid username/password.. Please check and re-try login"');
}
}
else{
echo "Query Execution Failed";
}
}
else{
echo "Failed to Prepare Sql Statement";
}
?>
答案 0 :(得分:0)
即使您可能找到了解决方案,我也想亲自向您展示(使用您的代码进行测试)。
我首先告诉您,您的问题实际上是您不使用异常处理。如果你这样做了,你会发现你的php / mysqli引发的真正的异常/错误。我建议您始终应用异常处理,至少在您查询数据库时。我将向您介绍封装在完整异常处理代码中的解决方案。如果您需要进一步解释,请随时向我询问。
首先让我们看看你的代码(只是第二个,查询部分是相关的),由我编辑并带入我的表格。
<?php
/*
* Tested on table "user":
*
* ------------------------
* id username password
* ------------------------
* 1 John Smith
* 2 John Mark
*/
try {
// Your received POST values.
$uname = 'John';
$pass = 'Smith';
//---------------------------------------------------------
// Connect to db.
//---------------------------------------------------------
$con = mysqli_connect('<server>', '<user>', '<pass>', '<db>');
if (!$con) {
throw new Exception('Connect error:<br/><br/>' . mysqli_connect_errno() . ' - ' . mysqli_connect_error());
}
//---------------------------------------------------------
// Sql statement.
//---------------------------------------------------------
$query = "SELECT * FROM user WHERE user.username = ? AND user.password = ?";
//---------------------------------------------------------
// Prepare sql statement.
//---------------------------------------------------------
$stmt = mysqli_prepare($con, $query);
if (!$stmt) {
throw new Exception('The sql statement can not be prepared!');
}
//---------------------------------------------------------
// Binds variables to the prepared statement as parameters.
//---------------------------------------------------------
$bound = mysqli_stmt_bind_param($stmt, 'ss', $uname, $pass);
if (!$bound) {
throw new Exception('The variables could not be bound to the prepared statement!');
}
//---------------------------------------------------------
// Execute the prepared statement.
//---------------------------------------------------------
$executed = mysqli_stmt_execute($stmt);
if (!$executed) {
throw new Exception('The prepared statement could not be executed!');
}
//---------------------------------------------------------
// Transfers the result set from the prepared statement.
//---------------------------------------------------------
$stored = mysqli_stmt_store_result($stmt);
if (!$stored) {
throw new Exception('The result set from the prepared statement could not be transfered!');
}
//---------------------------------------------------------
// Get the number of rows in statements result set.
//---------------------------------------------------------
$rows = mysqli_stmt_num_rows($stmt);
if ($rows == 1) {
//---------------------------------------------------------
// Get the result set from the prepared statement.
//---------------------------------------------------------
$result = mysqli_stmt_get_result($stmt);
if (!$result) {
throw new Exception(mysqli_error($con));
//----------------------------------------------------------------
// OR:
//----------------------------------------------------------------
// Get a list of errors from the last command executed.
// Each error displayed as an associative array containing the
// errno, error, and sqlstate.
// Because array returned, then no exception thrown, just display.
//----------------------------------------------------------------
// $errorList = mysqli_error_list($con);
// echo '<pre>' . 'Error retrieving result set:<br/></br>' . print_r($errorList, true) . '</pre>';
// exit();
//----------------------------------------------------------------
}
//---------------------------------------------------------
// Read the result set.
//---------------------------------------------------------
$row = mysqli_fetch_array($result, MYSQLI_ASSOC);
if (!isset($row)) {
echo 'No records returned!';
exit();
}
echo 'Returned username is: ' . $row['username'];
} else {
echo 'Invalid username/password. Please check and retry login';
}
//-----------------------------------------------------------
// Frees stored result memory for the given statement handle.
//-----------------------------------------------------------
mysqli_stmt_free_result($stmt);
//---------------------------------------------------------
// Close db connection.
//---------------------------------------------------------
$closed = mysqli_close($con);
if (!$closed) {
throw new Exception('The database connection can not be closed!');
}
} catch (Exception $exception) {
echo '<pre>' . print_r($exception, true) . '</pre>';
exit();
}
如果您使用 mysqli_stmt_store_result()
和 mysqli_stmt_get_result()
运行此代码,您将获得
Exception Object
(
[message:protected] => Commands out of sync; you can't run this command now
[string:Exception:private] =>
[code:protected] => 0
[file:protected] => [...]/index.php
[line:protected] => 63
[trace:Exception:private] => Array
(
)
[previous:Exception:private] =>
[xdebug_message] => ( ! ) Exception: Commands out of sync; you can't run this command now in [...]/index.php on line 63
Call Stack
#TimeMemoryFunctionLocation
10.2170368808{main}( ).../index.php:0
)
或者以这种形式(参见我的代码):
Error retrieving result set:
Array
(
[0] => Array
(
[errno] => 2014
[sqlstate] => HY000
[error] => Commands out of sync; you can't run this command now
)
)
此异常( Commands out of sync; you can't run this command now
)指出,您无法同时运行两个查询。有关详细信息,请参阅this answer,例如。
您在问题中显示的警告实际上告诉您效果:您没有从通话中获得任何mysqli_result
$result = mysqli_stmt_get_result($stmt);
因此你的
$row = mysqli_fetch_array($result, MYSQLI_ASSOC);
接收 FALSE
作为参数($result
)并向您发出警告
警告:mysqli_fetch_array()期望参数1为mysqli_result, 给出的布尔值 E:\ XAMPP \ htdocs中\ JQ \ login_system_sql_injection_proof \ loginprocess.php 在第57行
为了解决这个问题,我将给你两个解决方案。
仅使用 mysqli_stmt_get_result()
mysqli_fetch_array()
:
<?php
/*
* Tested on table "user":
*
* ------------------------
* id username password
* ------------------------
* 1 John Smith
* 2 John Mark
*/
try {
$uname = 'John';
$pass = 'Smith';
//---------------------------------------------------------
// Connect to db.
//---------------------------------------------------------
$con = mysqli_connect('<server>', '<user>', '<pass>', '<db>');
if (!$con) {
throw new Exception('Connect error:<br/><br/>' . mysqli_connect_errno() . ' - ' . mysqli_connect_error());
}
//---------------------------------------------------------
// Sql statement.
//---------------------------------------------------------
$query = "SELECT * FROM user WHERE user.username = ? AND user.password = ?";
//---------------------------------------------------------
// Prepare sql statement.
//---------------------------------------------------------
$stmt = mysqli_prepare($con, $query);
if (!$stmt) {
throw new Exception('The sql statement can not be prepared!');
}
//---------------------------------------------------------
// Binds variables to the prepared statement as parameters.
//---------------------------------------------------------
$bound = mysqli_stmt_bind_param($stmt, 'ss', $uname, $pass);
if (!$bound) {
throw new Exception('The variables could not be bound to the prepared statement!');
}
//---------------------------------------------------------
// Execute the prepared statement.
//---------------------------------------------------------
$executed = mysqli_stmt_execute($stmt);
if (!$executed) {
throw new Exception('The prepared statement could not be executed!');
}
//---------------------------------------------------------
// Get the result set from the prepared statement.
//---------------------------------------------------------
$result = mysqli_stmt_get_result($stmt);
if (!$result) {
throw new Exception(mysqli_error($con));
}
//---------------------------------------------------------
// Get the number of rows in statements result set.
//---------------------------------------------------------
$rows = mysqli_num_rows($result);
if ($rows == 1) {
//---------------------------------------------------------
// Read the result set.
//---------------------------------------------------------
$row = mysqli_fetch_array($result, MYSQLI_ASSOC);
if (!isset($row)) {
echo 'No records returned!';
exit();
}
echo 'Returned username is: ' . $row['username'];
} else {
echo 'Invalid username/password. Please check and retry login';
}
//-----------------------------------------------------------
// Frees stored result memory for the given statement handle.
//-----------------------------------------------------------
mysqli_stmt_free_result($stmt);
//---------------------------------------------------------
// Close db connection.
//---------------------------------------------------------
$closed = mysqli_close($con);
if (!$closed) {
throw new Exception('The database connection can not be closed!');
}
} catch (Exception $exception) {
echo '<pre>' . print_r($exception, true) . '</pre>';
exit();
}
将 mysqli_stmt_store_result()
与 mysqli_stmt_bind_result()
和 mysqli_stmt_fetch()
一起使用
<?php
/*
* Tested on table "user":
*
* ------------------------
* id username password
* ------------------------
* 1 John Smith
* 2 John Mark
*/
try {
$uname = 'John';
$pass = 'Smith';
//---------------------------------------------------------
// Connect to db.
//---------------------------------------------------------
$con = mysqli_connect('<server>', '<user>', '<pass>', '<db>');
if (!$con) {
throw new Exception('Connect error:<br/><br/>' . mysqli_connect_errno() . ' - ' . mysqli_connect_error());
}
//---------------------------------------------------------
// Sql statement.
//---------------------------------------------------------
$query = "SELECT * FROM user WHERE user.username = ? AND user.password = ?";
//---------------------------------------------------------
// Prepare sql statement.
//---------------------------------------------------------
$stmt = mysqli_prepare($con, $query);
if (!$stmt) {
throw new Exception('The sql statement can not be prepared!');
}
//---------------------------------------------------------
// Binds variables to the prepared statement as parameters.
//---------------------------------------------------------
$bound = mysqli_stmt_bind_param($stmt, 'ss', $uname, $pass);
if (!$bound) {
throw new Exception('The variables could not be bound to the prepared statement!');
}
//---------------------------------------------------------
// Execute the prepared statement.
//---------------------------------------------------------
$executed = mysqli_stmt_execute($stmt);
if (!$executed) {
throw new Exception('The prepared statement could not be executed!');
}
//---------------------------------------------------------
// Transfers the result set from the prepared statement.
//---------------------------------------------------------
$stored = mysqli_stmt_store_result($stmt);
if (!$stored) {
throw new Exception('The result set from the prepared statement could not be transfered!');
}
//---------------------------------------------------------
// Get the number of rows in statements result set.
//---------------------------------------------------------
$rows = mysqli_stmt_num_rows($stmt);
if ($rows == 1) {
//---------------------------------------------------------
// Bind result set columns to variables.
//---------------------------------------------------------
$bound = mysqli_stmt_bind_result($stmt, $resId, $resUsername, $resPassword);
if (!$bound) {
throw new Exception('The result set columns could not be bound to the variables');
}
//--------------------------------------------------------------------
// Fetch results from the prepared statement into the bound variables.
//--------------------------------------------------------------------
while (mysqli_stmt_fetch($stmt)) {
echo 'Successfully returned data:<br/><br/>';
echo 'ID is: ' . $resId . '<br/>';
echo 'Username is: ' . $resUsername . '<br/>';
echo 'Password is: ' . $resPassword . '<br/>';
}
} else {
echo 'Invalid username/password. Please check and retry login';
}
//-----------------------------------------------------------
// Frees stored result memory for the given statement handle.
//-----------------------------------------------------------
mysqli_stmt_free_result($stmt);
//---------------------------------------------------------
// Close db connection.
//---------------------------------------------------------
$closed = mysqli_close($con);
if (!$closed) {
throw new Exception('The database connection can not be closed!');
}
} catch (Exception $exception) {
echo '<pre>' . print_r($exception, true) . '</pre>';
exit();
}
除了代码之外,我还添加了异常处理和mysqli_stmt_free_result($stmt)
函数来释放结果集占用的内存。