我有一个update information
表单,它做两件事:
- 更新数据库表中已有的信息
- 添加以前未存储在数据库表中的信息
下面是我的PHP代码:
<?php
require_once("../includes/database.php");
?>
<?php
// restricts access to logged in users only
session_start();
if(isset($_SESSION['student_id'])) {
// do nothing
}
else {
header('Location: login.php');
}
?>
<?php
//mysql_
$connection = mysqli_connect($dbhost, $dbuser, $dbpass, $dbname);
if(mysqli_connect_errno())
{
die("Database connection failed: " .
mysqli_connect_error() .
" (" . mysqli_connect_errno() . ")");
}
?>
<?php
// retrieves current user information
$student_id = $_SESSION['student_id'];
$query1 = "SELECT * FROM students WHERE student_id = {$student_id}";
$result1 = mysqli_query($connection, $query1);
$row = mysqli_fetch_assoc($result1);
$_SESSION["fname"] = $row["f_name"];
$_SESSION["lname"] = $row["l_name"];
$_SESSION["email"] = $row["email"];
$_SESSION["key"] = $row["password"];
?>
<?php
// updates database with updated user info
if(isset($_POST['update'])) {
$update_f_name = $_POST['fname'];
$update_l_name = $_POST['lname'];
$update_email = $_POST['email'];
$update_pword = $_POST['key'];
$insert_username = $_POST['username'];
$insert_city = $_POST['city'];
$insert_state = $_POST['state'];
$insert_zip = $_POST['zip'];
$insert_bio = $_POST['bio'];
//updates information already in the db
$query ="UPDATE students
SET f_name = '{$update_f_name}',
l_name = '{$update_l_name}',
email = '{$update_email}',
password = '{$update_pword}'
WHERE student_id='{$student_id}'";
//inserts additional information into the db
$query2 = "INSERT INTO students
(username, city, state, zip, bio)
VALUES('{$insert_username}', '{$insert_city}', '{$insert_state}', '{$insert_zip}', '{$insert_bio}')
WHERE student_id = '{$student_id}'";
$result2 = mysqli_query($connection, $query2);
$result = mysqli_query($connection, $query);
if(!$result and !result2){
die("Database query failed.". mysqli_error($connection));
}
header('Location: dashboard.php');
}
没有显示任何错误,并且重定向(成功地重定向到同一页面)。但是,当我在phpmyadmin中检查数据库时,应该插入的列($query2
字符串中的列)仍然具有值NULL
。
以下是我的数据库架构:
CREATE TABLE students
(
student_id INT NOT NULL AUTO_INCREMENT,
username VARCHAR(30),
email VARCHAR(80),
password VARCHAR(30),
f_name VARCHAR(30),
l_name VARCHAR(30),
bio VARCHAR(350),
dp VARCHAR(15),
is_suspended CHAR(1) DEFAULT '0' NOT NULL,
suspension_reason VARCHAR(150),
role_id INT NOT NULL,
created_on DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_on TIMESTAMP,
is_active CHAR(1) DEFAULT '1' NOT NULL,
city VARCHAR(15) NOT NULL,
state VARCHAR(15) NOT NULL,
zip VARCHAR(6) NOT NULL,
b_day DATE,
CONSTRAINT students_id_pk PRIMARY KEY(student_id),
CONSTRAINT students_role_id_fk FOREIGN KEY(role_id) REFERENCES user_roles(role_id) ON DELETE CASCADE,
CONSTRAINT students_username_uq UNIQUE(username),
CONSTRAINT students_email_uq UNIQUE(email)
);
EDIT:我知道我的代码容易受到SQL注入的影响。我将在更新后实现它。
查看您的第二个查询,MySQL INSERT语法不支持WHERE子句,因此您的查询将失败。
此外,我看不到在同一个表中更新和插入语句背后的逻辑。您的"student_id"是PRIMARY KEY,因此假设该键存在,并且您的第一个Update语句成功,INSERT自然会失败,因为主键已经存在。
您可能需要使用将其更改为单个语句;插入。。。正在进行重复密钥更新。。。
例如
INSERT INTO students
(student_id, username, city, state, zip, bio)
VALUES('{$student_id}', '{$insert_username}', '{$insert_city}', '{$insert_state}', '{$insert_zip}', '{$insert_bio}')
ON DUPLICATE KEY UPDATE
f_name = '{$update_f_name}',
l_name = '{$update_l_name}',
email = '{$update_email}',
password = '{$update_pword}'";
请参阅http://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html
只有当两个更新语句都失败时,脚本才会退出。
还有一点,如果这是一个完整的脚本,你应该真正考虑数据输入的安全性,以及检查用户是否登录的机制。也不需要停止PHP解释器,因为这将在脚本执行之前创建浏览器输出。
如果从客户端获取$_POST
数据,则需要避免SQL注入(请参阅PHP和SQL注入)。
然而,我有一种感觉,它插入了空值,因为$_POST
变量不存在。我建议对你的价值观进行isset()
检查。
啊哈,发现你的错误了。如果您有if(!$result and !result2){
,那么只有当$result
和$result2
都失败时,您的代码才会失效。把它改成OR(||),你就可以出发了!
if(!$result || !result2){
是的,Riggs说,没有必要一直打开和关闭PHP标签(<?php
)。如果您的脚本完全是PHP,那么您可以安全地使用<?php
开始脚本,而不必为结束标记而烦恼。
session_start()
将不起作用,因为您用一个空行将php的第一个块与第二个块分隔开,该空行将空间输出到输出缓冲区。在向输出缓冲区输出任何内容之前,必须运行session_start()
,所以像这样进行更改
如果你查看了你的PHP错误日志,你会看到一个错误
<?php
// restricts access to logged in users only
session_start();
require_once("../includes/database.php");
if(isset($_SESSION['student_id'])) {
// do nothing
} else {
header('Location: login.php');
}
?>
完全没有必要一直用这些<?php ... ?>
<?php ... ?>
来启动和停止PHP解释器
您只需要在PHP代码的开头有一个<?php
,在代码的末尾有一个?>
。
同样的原因,header()
也不会工作!
您的代码中也充满了SQL注入属性。请阅读此内容,了解如何停止此操作。
这条线也是的一个问题
if(!$result and !result2){
应该是
if(!$result or !result2){
但当然,这会使您的数据库部分更新,即一个或另一个查询会发生,但另一个不会。
您还需要查看事务处理
这也是的一个问题
$query2 = "INSERT INTO students
(username, city, state, zip, bio)
VALUES('{$insert_username}', '{$insert_city}', '{$insert_state}', '{$insert_zip}', '{$insert_bio}')
WHERE student_id = '{$student_id}'";
由于INSERT不具有或不支持WHERE子句,