我正在建立一个完整的HTML / PHP / CSS网站用于学习,因为这是我的第一个网站。我的网站主题是私人培训师[gym〜workout〜sport],我将软件包添加到数据库中,只有培训师可以添加这些软件包,也可以更新它们以更改内部信息。
有3个计划:免费,银牌,金牌,以更新培训师必须使用其用户名+密码的软件包。 如果正确,则应显示以下消息:更新成功 如果用户名或密码错误,则应显示以下消息:无法更新
问题是当他选择计划并输入正确的用户和密码时,它正在工作并显示成功消息,但是如果他输入错误的用户或密码,则它仍在显示成功消息,但未在数据库中更新。
这是PHP:
<?php
//Create connection to the database.
$host="localhost"; // Host name
$dbusername="root"; //username
$dbpassword=""; //username password
$dbname="proil"; //db name
// Connect to server and select database.
$con = mysqli_connect($host,$dbusername,$dbpassword,$dbname);
//Input posted data.
$zehut = $_POST["id"];
$answer = $_POST['pickclass'];
$pass = $_POST['pass'];
$count=0;
if ($answer == "free") {
$query = "UPDATE trainer_packages AS b
INNER JOIN trainer_d AS g ON b.trainer_pack_id = g.id
SET b.package__name= 'free'
WHERE b.trainer_pack_id = '$zehut' and g.pass ='$pass' ";
$count=$count+1;
}
if ($answer == "silver") {
$query = "UPDATE trainer_packages AS b
INNER JOIN trainer_d AS g ON b.trainer_pack_id = g.id
SET b.package__name= 'silver'
WHERE b.trainer_pack_id = '$zehut' and g.pass ='$pass' ";
$count=$count+1;
}
if ($answer == "gold") {
$query = "UPDATE trainer_packages AS b
INNER JOIN trainer_d AS g ON b.trainer_pack_id = g.id
SET b.package__name= 'gold'
WHERE b.trainer_pack_id = '$zehut' and g.pass ='$pass' ";
$count=$count+1;
}
//Run SQL query
mysqli_query($con, $query) or die ("ERROR: Cannot do insert ".mysqli_error($con));
if (mysqli_query($con, $query)) {
echo "Update successful.";
} else {
echo "Could not update: " . mysqli_error($con);
}
//Close the SQL connection.
mysqli_close($con);
?>
答案 0 :(得分:1)
您有一些问题需要解决。除了使用password_hash()
and password_verify()
第一个是您两次致电mysqli_query($con, $query)
。
您需要删除mysqli_query($con, $query) or die ("ERROR: Cannot do insert ".mysqli_error($con));
行。
PHP结束符?>
也是多余的,在不切换语言时,应该省略PHP结束符,以防止意外的原始文本处理和显示,否则会发生。
使用mysqli_error($con)
向最终用户输出查询错误被认为是不好的做法。显示错误消息可能会将敏感的详细信息暴露给最终用户,这些详细信息可用于进一步对您的应用程序进行攻击。
您应该记录错误。请为您的应用程序研究合适的日志记录方法。
如评论中所述,您的查询需要进行SQL注入。对于接受用户土地数据的任何查询,您都应实现prepared statements。
mysqli_query($con, $query)
仅在失败时返回false
,例如SELECT FROM NOTVALID
。相反,您需要检查mysqli_affected_rows($con)
。
if (mysqli_query($con, $query)) {
if (mysqli_affected_rows($con) > 0) {
echo "Update successful.";
} else {
echo "No changes were made.";
}
} else {
echo "Could not update";
}
我建议在发出SELECT FROM trainer_d
查询之前,将查询分为UPDATE trainer_packages
并以无效的用户名/密码错误失败。
<?php
//... omitted for brevity
// Connect to server and select database.
$con = new mysqli($host, $dbusername, $dbpassword, $dbname);
//enable exception handling for mysqli
$driver = new mysqli_driver();
$driver->report_mode = MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT;
// Input posted data.
$zehut = $_POST['id'];
$answer = $_POST['pickclass'];
$pass = $_POST['pass'];
try {
// Validate the user
$isValid = false;
$stmt = $con->prepare('SELECT EXISTS(
SELECT 1
FROM trainer_d AS g
INNER JOIN trainer_packages AS b
ON b.trainer_pack_id = g.id
WHERE g.id = ?
AND g.pass = ?)');
$stmt->bind_param('ss', $zehut, $pass);
$stmt->execute();
$stmt->bind_result($isValid);
$stmt->fetch();
$stmt->close();
if (!$isValid) {
throw new InvalidArgumentException('Invalid username and/or password.');
}
if (!in_array($answer, ['free', 'silver', 'gold'], true)) {
//validate package
throw new InvalidArgumentException('Invalid package selected.');
}
// Update the training package
$stmt = $con->prepare('UPDATE trainer_packages AS b
SET b.package__name = ?
WHERE b.trainer_pack_id = ?');
$stmt->bind_param('ss', $answer, $zehut);
$stmt->execute();
$stmt->close();
echo 'Update successful.';
} catch (Exception $e) {
if ($e instanceof InvalidArgumentException) {
//catch specific exception to handle them
echo $e->getMessage();
exit;
}
//handle other exceptions
die('Could not update.');
} finally {
//Close the SQL connection.
$con->close();
}