使用 PHP 中的用户首选项更新帐户 table
Update accounts table with the user preferences in PHP
我有以下 SQL 数据库:
CREATE TABLE IF NOT EXISTS `accounts` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`password` varchar(255) NOT NULL,
`email` varchar(100) NOT NULL,
'experience' enum('Beginner', 'Intermediate', 'Advanced) NULL, Default Beginner,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
INSERT INTO `accounts` (`id`, `username`, `password`, `email`, 'experience') VALUES (1, 'test', 'y$SfhYIDtn.iOuCW7zfoFLuuZHX6lja4lF4XA4JqNmpiH/.P3zB8JCa', 'test@test.com');
除此之外,我还有一个注册表单,它将使用注册表单将给定的值填充到数据库中。
下面的 HTML 表格将成为更新表格:
<div class="card bg-light">
<div class="register">
<h1>Update My Preferences</h1>
<form action="update_preferences.php" method="post" autocomplete="off">
<div class="form-group input-group">
<select name="new_experience" class="form-control">
<option selected="">Change Investment Experience</option>
<option>Beginner</option>
<option>Intermediate</option>
<option>Advanced</option>
</select>
</div>
<!-- form-group end.// -->
<label for="username">
<i class="fas fa-user"></i>
</label>
<input type="text" name="new_username" value="<?=$_SESSION['name']?>" id="username">
<label for="password">
<i class="fas fa-lock"></i>
</label>
<input type="password" name="new_password" placeholder="" value="" id="password">
<label for="email">
<i class="fas fa-envelope"></i>
</label>
<input type="email" name="new_email" value="<?=$email?>" id="email">
<input type="submit" value="Update">
</form>
</div>
</div>
我设法为 update_preferences.php
添加了以下代码,但后来我遇到了错误“无法准备语句!
致命错误:在第 71 行的 /home2/freemark/public_html/update_preferences.php 中调用布尔值的成员函数 close()":
<?php
// Change this to your connection info.
$DATABASE_HOST = 'localhost';
$DATABASE_USER = 'root';
$DATABASE_PASS = '';
$DATABASE_NAME = 'phplogindb';
// Try and connect using the info above.
$con = mysqli_connect($DATABASE_HOST, $DATABASE_USER, $DATABASE_PASS, $DATABASE_NAME);
if (mysqli_connect_errno()) {
// If there is an error with the connection, stop the script and display the error.
die ('Failed to connect to MySQL: ' . mysqli_connect_error());
}
// Now we check if the data was submitted, isset() function will check if the data exists.
if (!isset($_POST['new_experience'], $_POST['new_username'], $_POST['new_password'], $_POST['new_email'])) {
// Could not get the data that should have been sent.
die ('Please complete the registration form!');
}
// Make sure the submitted registration values are not empty.
if (empty($_POST['new_experience']) || empty($_POST['new_username']) || empty($_POST['new_password']) || empty($_POST['new_email'])) {
// One or more values are empty.
die ('Please complete the registration form');
}
$new_exp_level=$_POST['new_experience'];
$new_username=$_POST['new_username'];
$new_password=$_POST['new_password'];
$new_email=$_POST['new_email'];
// We need to check if the account with that username exists.
if ($stmt = $con->prepare('SELECT id, password FROM accounts WHERE username = ?')) {
if (!filter_var($_POST['new_email'], FILTER_VALIDATE_EMAIL)) {
die ('Email is not valid!');
}
if (preg_match('/[A-Za-z0-9]+/', $_POST['new_username']) == 0) {
die ('Username is not valid!');
}
if (strlen($_POST['new_password']) > 20 || strlen($_POST['new_password']) < 5) {
die ('Password must be between 5 and 20 characters long!');
}
// Bind parameters (s = string, i = int, b = blob, etc), hash the password using the PHP password_hash function.
$stmt->bind_param('s', $_POST['new_username']);
$stmt->execute();
$stmt->store_result();
// Store the result so we can check if the account exists in the database.
if ($stmt->num_rows > 0) {
// Username already exists
echo 'Username exists, please choose another!';
} else {
// Username doesnt exists, insert new account
if ($stmt = $con->prepare('UPDATE accounts SET $new_exp_level = ?, $new_username = ?, $new_password = ?, $new_email = ? WHERE id = ?')) {
// We do not want to expose passwords in our database, so hash the password and use password_verify when a user logs in.
$password = password_hash($_POST['new_password'], PASSWORD_DEFAULT);
$stmt->bind_param('ssss', $_POST['new_username'], $password, $_POST['new_email'], $_POST['new_experience']);
$stmt->execute();
header('Location: login.html');
exit();
echo 'You have successfully registered, you can now login!';
}
else {
// Something is wrong with the sql statement, check to make sure accounts table exists with all 3 fields.
echo 'Could not prepare statement!';
}
}
$stmt->close();
} else {
// Something is wrong with the sql statement, check to make sure accounts table exists with all 3 fields.
echo 'Could not prepare statement!';
}
$con->close();
?>
不确定您遇到了什么问题,但查询多个字段更新如下所示:
$sql = "UPDATE accounts SET field1 = ?, field2 = ?, field3 = ? WHERE id = ?";
// binding values can be done something like
$stmt->bind_param('ssss', $variable1, $variable2, $variable3, $_SESSION['id']);
另外,阅读this page关于密码散列和从不存储明文密码。
if(empty($new_password){
缺少右括号
if(empty($new_password) *)*{
由于您的更新,您的错误在这里:
else {
// Something is wrong with the sql statement, check to make sure accounts table exists with all 3 fields.
echo 'Could not prepare statement!';
}
}
$stmt->close(); <-- this is line 71 (after pasting your code into my IDE so i assume it's the full content)
所以 $stmt
没有名为 'close
的方法。我认为这应该说 $con->close();
真的,如果一个错误是将您指向带有确切消息的确切行,那么调试起来应该不会太困难
-- 更新--
我还注意到你没有绑定足够的参数
UPDATE accounts SET $new_exp_level = ?, $new_username = ?, $new_password = ?, $new_email = ? WHERE id = ? //<-- 5 placeholders
$stmt->bind_param('ssss', $_POST['new_username'], $password, $_POST['new_email'], $_POST['new_experience']); // <-- 4 params
我有以下 SQL 数据库:
CREATE TABLE IF NOT EXISTS `accounts` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`password` varchar(255) NOT NULL,
`email` varchar(100) NOT NULL,
'experience' enum('Beginner', 'Intermediate', 'Advanced) NULL, Default Beginner,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
INSERT INTO `accounts` (`id`, `username`, `password`, `email`, 'experience') VALUES (1, 'test', 'y$SfhYIDtn.iOuCW7zfoFLuuZHX6lja4lF4XA4JqNmpiH/.P3zB8JCa', 'test@test.com');
除此之外,我还有一个注册表单,它将使用注册表单将给定的值填充到数据库中。
下面的 HTML 表格将成为更新表格:
<div class="card bg-light">
<div class="register">
<h1>Update My Preferences</h1>
<form action="update_preferences.php" method="post" autocomplete="off">
<div class="form-group input-group">
<select name="new_experience" class="form-control">
<option selected="">Change Investment Experience</option>
<option>Beginner</option>
<option>Intermediate</option>
<option>Advanced</option>
</select>
</div>
<!-- form-group end.// -->
<label for="username">
<i class="fas fa-user"></i>
</label>
<input type="text" name="new_username" value="<?=$_SESSION['name']?>" id="username">
<label for="password">
<i class="fas fa-lock"></i>
</label>
<input type="password" name="new_password" placeholder="" value="" id="password">
<label for="email">
<i class="fas fa-envelope"></i>
</label>
<input type="email" name="new_email" value="<?=$email?>" id="email">
<input type="submit" value="Update">
</form>
</div>
</div>
我设法为 update_preferences.php
添加了以下代码,但后来我遇到了错误“无法准备语句!
致命错误:在第 71 行的 /home2/freemark/public_html/update_preferences.php 中调用布尔值的成员函数 close()":
<?php
// Change this to your connection info.
$DATABASE_HOST = 'localhost';
$DATABASE_USER = 'root';
$DATABASE_PASS = '';
$DATABASE_NAME = 'phplogindb';
// Try and connect using the info above.
$con = mysqli_connect($DATABASE_HOST, $DATABASE_USER, $DATABASE_PASS, $DATABASE_NAME);
if (mysqli_connect_errno()) {
// If there is an error with the connection, stop the script and display the error.
die ('Failed to connect to MySQL: ' . mysqli_connect_error());
}
// Now we check if the data was submitted, isset() function will check if the data exists.
if (!isset($_POST['new_experience'], $_POST['new_username'], $_POST['new_password'], $_POST['new_email'])) {
// Could not get the data that should have been sent.
die ('Please complete the registration form!');
}
// Make sure the submitted registration values are not empty.
if (empty($_POST['new_experience']) || empty($_POST['new_username']) || empty($_POST['new_password']) || empty($_POST['new_email'])) {
// One or more values are empty.
die ('Please complete the registration form');
}
$new_exp_level=$_POST['new_experience'];
$new_username=$_POST['new_username'];
$new_password=$_POST['new_password'];
$new_email=$_POST['new_email'];
// We need to check if the account with that username exists.
if ($stmt = $con->prepare('SELECT id, password FROM accounts WHERE username = ?')) {
if (!filter_var($_POST['new_email'], FILTER_VALIDATE_EMAIL)) {
die ('Email is not valid!');
}
if (preg_match('/[A-Za-z0-9]+/', $_POST['new_username']) == 0) {
die ('Username is not valid!');
}
if (strlen($_POST['new_password']) > 20 || strlen($_POST['new_password']) < 5) {
die ('Password must be between 5 and 20 characters long!');
}
// Bind parameters (s = string, i = int, b = blob, etc), hash the password using the PHP password_hash function.
$stmt->bind_param('s', $_POST['new_username']);
$stmt->execute();
$stmt->store_result();
// Store the result so we can check if the account exists in the database.
if ($stmt->num_rows > 0) {
// Username already exists
echo 'Username exists, please choose another!';
} else {
// Username doesnt exists, insert new account
if ($stmt = $con->prepare('UPDATE accounts SET $new_exp_level = ?, $new_username = ?, $new_password = ?, $new_email = ? WHERE id = ?')) {
// We do not want to expose passwords in our database, so hash the password and use password_verify when a user logs in.
$password = password_hash($_POST['new_password'], PASSWORD_DEFAULT);
$stmt->bind_param('ssss', $_POST['new_username'], $password, $_POST['new_email'], $_POST['new_experience']);
$stmt->execute();
header('Location: login.html');
exit();
echo 'You have successfully registered, you can now login!';
}
else {
// Something is wrong with the sql statement, check to make sure accounts table exists with all 3 fields.
echo 'Could not prepare statement!';
}
}
$stmt->close();
} else {
// Something is wrong with the sql statement, check to make sure accounts table exists with all 3 fields.
echo 'Could not prepare statement!';
}
$con->close();
?>
不确定您遇到了什么问题,但查询多个字段更新如下所示:
$sql = "UPDATE accounts SET field1 = ?, field2 = ?, field3 = ? WHERE id = ?";
// binding values can be done something like
$stmt->bind_param('ssss', $variable1, $variable2, $variable3, $_SESSION['id']);
另外,阅读this page关于密码散列和从不存储明文密码。
if(empty($new_password){
缺少右括号
if(empty($new_password) *)*{
由于您的更新,您的错误在这里:
else {
// Something is wrong with the sql statement, check to make sure accounts table exists with all 3 fields.
echo 'Could not prepare statement!';
}
}
$stmt->close(); <-- this is line 71 (after pasting your code into my IDE so i assume it's the full content)
所以 $stmt
没有名为 'close
的方法。我认为这应该说 $con->close();
真的,如果一个错误是将您指向带有确切消息的确切行,那么调试起来应该不会太困难 -- 更新--
我还注意到你没有绑定足够的参数
UPDATE accounts SET $new_exp_level = ?, $new_username = ?, $new_password = ?, $new_email = ? WHERE id = ? //<-- 5 placeholders
$stmt->bind_param('ssss', $_POST['new_username'], $password, $_POST['new_email'], $_POST['new_experience']); // <-- 4 params