从0到1学PHP(八):PHP 与 MySQL 数据库:数据持久化存储
目录
- 一、MySQL 数据库基础
- 1.1 数据库与表的概念及创建方法
- 1.2 SQL 基本语句
- 1.2.1 SELECT 语句
- 1.2.2 INSERT 语句
- 1.2.3 UPDATE 语句
- 1.2.4 DELETE 语句
- 二、PHP 连接 MySQL 数据库
- 2.1 使用 mysqli 扩展连接数据库的步骤
- 2.2 PDO 连接数据库的方法及优势
- 三、数据库操作(CRUD)
- 3.1 插入数据(INSERT)的 PHP 实现
- 3.2 查询数据(SELECT)并展示结果
- 3.3 更新数据(UPDATE)和删除数据(DELETE)的操作
- 四、数据库事务与预处理语句
- 4.1 事务的 ACID 特性及在 PHP 中的实现
- 4.2 预处理语句防止 SQL 注入及提高执行效率
- 4.2.1 SQL 注入原理
- 4.2.2 预处理语句防止 SQL 注入和提高执行效率的原理
- 4.2.3 代码示例
一、MySQL 数据库基础
1.1 数据库与表的概念及创建方法
数据库(Database)是按照数据结构来组织、存储和管理数据的仓库,是一个长期存储在计算机内的、有组织的、可共享的、统一管理的大量数据的集合 。它就像是一个大仓库,里面可以存放各种数据。而表(Table)是数据库中的一个对象,用于存储具体的数据,通常以二维表格的形式存在,由行和列组成,每一行代表一个数据记录,每一列代表一种数据类型。比如在一个学生管理系统的数据库中,可能有一个 “students” 表,用来存储学生的相关信息,每一行对应一个学生,列则可能包含学生 ID、姓名、年龄、性别等字段。
在 MySQL 中,使用CREATE DATABASE语句来创建数据库,基本语法如下:
CREATE DATABASE database_name;
例如,创建一个名为 “test_db” 的数据库:
CREATE DATABASE test_db;
创建表则使用CREATE TABLE语句,在创建表时需要指定表名以及各个列的名称、数据类型和约束条件等。基本语法如下:
CREATE TABLE table_name (column1 data_type constraint,column2 data_type constraint,...
);
比如在刚才创建的 “test_db” 数据库中创建一个 “students” 表:
USE test_db; -- 先使用test_db数据库CREATE TABLE students (student_id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(50) NOT NULL,age INT,gender ENUM('男', '女')
);
上述代码中,student_id列是一个自增长的整数类型,作为主键,保证每条记录的唯一性;name列是字符串类型,长度为 50,且不允许为空;age列是整数类型;gender列是枚举类型,取值只能是 ’ 男’ 或 ’ 女’ 。
1.2 SQL 基本语句
1.2.1 SELECT 语句
SELECT语句用于从数据库表中查询数据,是 SQL 中最常用的语句之一。其基本语法如下:
SELECT column1, column2, ...
FROM table_name
WHERE condition;
- column1, column2, …:指定要查询的列,如果要查询所有列,可以使用*。
- table_name:指定要查询的表名。
- WHERE condition:可选的筛选条件,用于过滤出符合条件的数据,只有满足条件的记录才会被返回。
例如,从 “students” 表中查询所有学生的姓名和年龄:
SELECT name, age
FROM students;
如果要查询年龄大于 18 岁的学生信息,则可以加上WHERE条件:
SELECT *
FROM students
WHERE age > 18;
1.2.2 INSERT 语句
INSERT语句用于向表中插入新的数据记录。基本语法有两种形式:
- 插入指定列的数据:
INSERT INTO table_name (column1, column2, ...)
VALUES (value1, value2, ...);
- 插入所有列的数据(此时列名可以省略):
INSERT INTO table_name
VALUES (value1, value2, ...);
例如,向 “students” 表中插入一条学生记录:
INSERT INTO students (name, age, gender)
VALUES ('张三', 20, '男');
1.2.3 UPDATE 语句
UPDATE语句用于修改表中已存在的数据记录。基本语法如下:
UPDATE table_name
SET column1 = value1, column2 = value2, ...
WHERE condition;
- SET后面指定要更新的列及其新值。
- WHERE条件用于指定要更新哪些记录,如果省略WHERE条件,则会更新表中的所有记录。
例如,将 “students” 表中姓名为 “张三” 的学生年龄更新为 21 岁:
UPDATE students
SET age = 21
WHERE name = '张三';
1.2.4 DELETE 语句
DELETE语句用于从表中删除数据记录。基本语法如下:
DELETE FROM table_name
WHERE condition;
同样,WHERE条件用于指定要删除哪些记录,如果省略WHERE条件,将会删除表中的所有数据。
例如,删除 “students” 表中姓名为 “张三” 的学生记录:
DELETE FROM students
WHERE name = '张三';
这些基本的 SQL 语句是操作 MySQL 数据库的基础,通过灵活运用它们,可以实现对数据库中数据的各种管理和操作。
二、PHP 连接 MySQL 数据库
2.1 使用 mysqli 扩展连接数据库的步骤
mysqli扩展是 PHP 中用于连接和操作 MySQL 数据库的扩展,它提供了面向对象和面向过程两种编程风格。使用mysqli扩展连接 MySQL 数据库一般包含以下步骤:
- 创建连接:使用mysqli_connect()函数(面向过程风格)或new mysqli()(面向对象风格)来创建与 MySQL 数据库服务器的连接。需要提供主机名、用户名、密码和数据库名等参数。
- 检查连接:连接创建后,需要检查连接是否成功。如果连接失败,获取并输出错误信息,终止后续操作。
- 设置字符编码:为了避免数据乱码问题,通常需要设置连接的字符编码,一般设置为utf8或utf8mb4。
- 使用连接进行数据库操作:连接成功且字符编码设置好后,就可以使用该连接执行各种 SQL 语句,如查询、插入、更新、删除等操作。
- 关闭连接:在完成所有数据库操作后,应关闭数据库连接,以释放资源。
以下是一个面向对象风格的mysqli连接示例代码:
<?php
// 数据库配置
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "test_db";// 创建连接
$conn = new mysqli($servername, $username, $password, $dbname);// 检查连接
if ($conn->connect_error) {die("连接失败: ". $conn->connect_error);
}// 设置字符编码
$conn->set_charset("utf8");echo "连接成功";// 关闭连接
$conn->close();
?>
2.2 PDO 连接数据库的方法及优势
PDO(PHP Data Objects)是 PHP 的一个数据库抽象层扩展,它允许通过一个统一的 API 来访问不同类型的数据库,如 MySQL、SQLite、PostgreSQL 等。使用 PDO 连接 MySQL 数据库的方法如下:
- 定义数据源名称(DSN):DSN 包含了连接数据库所需的基本信息,如数据库类型、主机名、数据库名、字符编码等。对于 MySQL 数据库,DSN 的格式通常为mysql:host=主机名;dbname=数据库名;charset=字符编码。
- 创建 PDO 实例:使用new PDO()创建 PDO 对象,传入 DSN、用户名和密码作为参数。同时,可以设置一些 PDO 属性,如错误处理模式等。
- 错误处理:通过try-catch块捕获可能出现的异常,以便在连接失败或执行数据库操作出错时进行处理。
以下是使用 PDO 连接 MySQL 数据库的示例代码:
<?php
// 数据库配置
$host = 'localhost';
$db = 'test_db';
$user = 'root';
$pass = '';
$charset = 'utf8mb4';$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,PDO::ATTR_EMULATE_PREPARES => false,
];try {$pdo = new PDO($dsn, $user, $pass, $options);echo "连接成功";
} catch (\PDOException $e) {throw new \PDOException($e->getMessage(), (int)$e->getCode());
}
?>
PDO 连接数据库具有以下优势:
- 安全性高:PDO 通过预处理语句和参数绑定的方式,将 SQL 语句和数据分开处理,有效防止 SQL 注入攻击 。例如在执行查询时,用户输入的数据不会直接拼接到 SQL 语句中,而是作为参数传递,这样恶意用户无法通过输入特殊字符来篡改 SQL 语句结构。
- 可移植性强:由于 PDO 是一个数据库抽象层,使用相同的 PDO 代码可以轻松切换不同类型的数据库,只需更改 DSN 和少量配置即可,大大提高了代码的可维护性和可移植性。比如从 MySQL 数据库切换到 SQLite 数据库,代码中大部分逻辑无需修改。
- 性能优化:PDO 支持数据库连接池,减少了每次连接数据库的开销,提高了应用程序的性能。同时,预处理语句在多次执行相同结构的 SQL 语句时,数据库引擎可以对其进行优化,提升执行效率。
- 面向对象编程:PDO 提供了简洁、面向对象的 API,使代码结构更加清晰,易于理解和维护。开发人员可以利用面向对象的特性,如封装、继承和多态,更好地组织和管理数据库操作相关的代码。
三、数据库操作(CRUD)
在 PHP 与 MySQL 数据库的交互中,CRUD 操作(创建 Create、读取 Read、更新 Update、删除 Delete)是最基本也是最重要的操作,它们负责对数据库中的数据进行管理和维护。
3.1 插入数据(INSERT)的 PHP 实现
使用mysqli扩展插入数据时,先创建连接,然后构建INSERT语句并使用query方法执行 。示例代码如下:
<?php
// 数据库配置
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "test_db";// 创建连接
$conn = new mysqli($servername, $username, $password, $dbname);// 检查连接
if ($conn->connect_error) {die("连接失败: ". $conn->connect_error);
}// 插入数据
$name = "李四";
$age = 22;
$gender = "女";
$sql = "INSERT INTO students (name, age, gender) VALUES ('$name', $age, '$gender')";if ($conn->query($sql) === TRUE) {echo "新记录插入成功";
} else {echo "Error: ". $sql. "<br>". $conn->error;
}// 关闭连接
$conn->close();
?>
上述代码中,先配置好数据库连接信息并建立连接,然后定义要插入的数据,构建INSERT语句,执行后根据执行结果输出相应信息。
使用 PDO 插入数据时,利用预处理语句和参数绑定来提高安全性和执行效率 。示例代码如下:
<?php
// 数据库配置
$host = 'localhost';
$db = 'test_db';
$user = 'root';
$pass = '';
$charset = 'utf8mb4';$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,PDO::ATTR_EMULATE_PREPARES => false,
];try {$pdo = new PDO($dsn, $user, $pass, $options);// 插入数据$name = "王五";$age = 23;$gender = "男";$sql = "INSERT INTO students (name, age, gender) VALUES (:name, :age, :gender)";$stmt = $pdo->prepare($sql);$stmt->execute(['name' => $name,'age' => $age,'gender' => $gender]);echo "新记录插入成功";
} catch (\PDOException $e) {throw new \PDOException($e->getMessage(), (int)$e->getCode());
}
?>
这里通过PDO创建连接,准备INSERT语句,使用execute方法并传入参数数组来执行插入操作,同时利用try-catch块处理可能出现的异常。
3.2 查询数据(SELECT)并展示结果
使用mysqli扩展查询数据并展示结果,通过query方法执行SELECT语句,然后使用fetch_assoc等方法获取结果并遍历展示。示例代码如下:
<?php
// 数据库配置
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "test_db";// 创建连接
$conn = new mysqli($servername, $username, $password, $dbname);// 检查连接
if ($conn->connect_error) {die("连接失败: ". $conn->connect_error);
}// 查询数据
$sql = "SELECT * FROM students";
$result = $conn->query($sql);if ($result->num_rows > 0) {while($row = $result->fetch_assoc()) {echo "学生ID: ". $row["student_id"]. " - 姓名: ". $row["name"]. " - 年龄: ". $row["age"]. " - 性别: ". $row["gender"]. "<br>";}
} else {echo "0 结果";
}// 关闭连接
$conn->close();
?>
该代码建立连接后执行查询语句,判断结果集中是否有数据,若有则逐行获取并输出学生信息。
使用 PDO 查询数据并展示结果的示例代码如下:
<?php
// 数据库配置
$host = 'localhost';
$db = 'test_db';
$user = 'root';
$pass = '';
$charset = 'utf8mb4';$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,PDO::ATTR_EMULATE_PREPARES => false,
];try {$pdo = new PDO($dsn, $user, $pass, $options);// 查询数据$sql = "SELECT * FROM students";$stmt = $pdo->query($sql);while ($row = $stmt->fetch()) {echo "学生ID: ". $row["student_id"]. " - 姓名: ". $row["name"]. " - 年龄: ". $row["age"]. " - 性别: ". $row["gender"]. "<br>";}
} catch (\PDOException $e) {throw new \PDOException($e->getMessage(), (int)$e->getCode());
}
?>
此代码通过PDO连接数据库,执行查询语句,使用fetch方法逐行获取结果并展示。
3.3 更新数据(UPDATE)和删除数据(DELETE)的操作
使用mysqli扩展更新数据,构建UPDATE语句并执行。示例代码如下:
<?php
// 数据库配置
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "test_db";// 创建连接
$conn = new mysqli($servername, $username, $password, $dbname);// 检查连接
if ($conn->connect_error) {die("连接失败: ". $conn->connect_error);
}// 更新数据
$new_age = 25;
$student_id = 1;
$sql = "UPDATE students SET age = $new_age WHERE student_id = $student_id";if ($conn->query($sql) === TRUE) {echo "记录更新成功";
} else {echo "Error: ". $sql. "<br>". $conn->error;
}// 关闭连接
$conn->close();
?>
上述代码中,先建立连接,然后定义更新后的年龄和要更新的学生 ID,构建UPDATE语句执行更新操作并输出结果。
使用mysqli扩展删除数据的示例代码如下:
<?php
// 数据库配置
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "test_db";// 创建连接
$conn = new mysqli($servername, $username, $password, $dbname);// 检查连接
if ($conn->connect_error) {die("连接失败: ". $conn->connect_error);
}// 删除数据
$student_id = 1;
$sql = "DELETE FROM students WHERE student_id = $student_id";if ($conn->query($sql) === TRUE) {echo "记录删除成功";
} else {echo "Error: ". $sql. "<br>". $conn->error;
}// 关闭连接
$conn->close();
?>
此代码定义要删除的学生 ID,构建DELETE语句执行删除操作。
使用 PDO 更新数据的示例代码如下:
<?php
// 数据库配置
$host = 'localhost';
$db = 'test_db';
$user = 'root';
$pass = '';
$charset = 'utf8mb4';$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,PDO::ATTR_EMULATE_PREPARES => false,
];try {$pdo = new PDO($dsn, $user, $pass, $options);// 更新数据$new_age = 26;$student_id = 2;$sql = "UPDATE students SET age = :new_age WHERE student_id = :student_id";$stmt = $pdo->prepare($sql);$stmt->execute(['new_age' => $new_age,'student_id' => $student_id]);echo "记录更新成功";
} catch (\PDOException $e) {throw new \PDOException($e->getMessage(), (int)$e->getCode());
}
?>
该代码通过PDO连接数据库,准备UPDATE语句,绑定参数后执行更新操作。
使用 PDO 删除数据的示例代码如下:
<?php
// 数据库配置
$host = 'localhost';
$db = 'test_db';
$user = 'root';
$pass = '';
$charset = 'utf8mb4';$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,PDO::ATTR_EMULATE_PREPARES => false,
];try {$pdo = new PDO($dsn, $user, $pass, $options);// 删除数据$student_id = 2;$sql = "DELETE FROM students WHERE student_id = :student_id";$stmt = $pdo->prepare($sql);$stmt->execute(['student_id' => $student_id]);echo "记录删除成功";
} catch (\PDOException $e) {throw new \PDOException($e->getMessage(), (int)$e->getCode());
}
?>
这里同样利用PDO准备DELETE语句,绑定参数后执行删除操作。通过这些示例,可以清晰地看到如何在 PHP 中使用mysqli和PDO扩展来完成数据库的更新和删除操作。
四、数据库事务与预处理语句
4.1 事务的 ACID 特性及在 PHP 中的实现
事务(Transaction)是数据库操作的一个逻辑单元,它包含一组操作,这些操作要么全部成功,要么全部失败 。事务具有 ACID 特性,这是数据库事务的核心原则:
- 原子性(Atomicity):事务是一个不可分割的最小单位,其中包含的所有操作要么全部成功执行,要么全部失败回滚 。比如在一个转账事务中,从账户 A 扣款和向账户 B 加款这两个操作必须同时成功,若其中任何一个操作失败,整个事务都要回滚,保证不会出现账户 A 扣款成功但账户 B 加款失败的情况,确保数据的完整性和一致性。
- 一致性(Consistency):事务执行前后,数据库的状态必须保持一致,即事务必须遵循数据库的约束规则,如唯一性、外键约束等 。例如,在一个库存管理系统中,商品的库存数量不能为负数,当进行商品出库操作时,如果库存数量不足,事务就会因为违反一致性规则而失败,保证库存数据的准确性。
- 隔离性(Isolation):多个事务并发执行时,一个事务的操作不会被其他事务干扰,每个事务都感觉不到其他事务的存在 。比如当多个用户同时进行转账操作时,数据库会通过一定的机制(如锁机制或 MVCC 多版本并发控制)来确保每个转账事务按顺序执行或避免冲突,防止出现数据混乱,如金额计算错误等问题。
- 持久性(Durability):事务一旦提交,它对数据库的修改就是永久性的,即使系统崩溃也不会丢失。例如,当完成一笔订单支付后,即使数据库服务器突然断电,支付记录也会通过数据库的日志等机制被永久保存下来。
在 PHP 中使用mysqli扩展实现事务的示例代码如下:
<?php
// 数据库配置
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "test_db";// 创建连接
$conn = new mysqli($servername, $username, $password, $dbname);// 检查连接
if ($conn->connect_error) {die("连接失败: ". $conn->connect_error);
}// 开始事务,设置为非自动提交
$conn->autocommit(false);$sql1 = "INSERT INTO students (name, age, gender) VALUES ('小明', 20, '男')";
$sql2 = "INSERT INTO students (name, age, gender) VALUES ('小红', 21, '女')";$result1 = $conn->query($sql1);
$result2 = $conn->query($sql2);if ($result1 && $result2) {// 所有操作成功,提交事务$conn->commit();echo "事务提交成功";
} else {// 有任何错误发生,回滚事务$conn->rollback();echo "事务回滚";
}// 恢复自动提交模式
$conn->autocommit(true);// 关闭连接
$conn->close();
?>
使用 PDO 实现事务的示例代码如下:
<?php
// 数据库配置
$host = 'localhost';
$db = 'test_db';
$user = 'root';
$pass = '';
$charset = 'utf8mb4';$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,PDO::ATTR_EMULATE_PREPARES => false,
];try {$pdo = new PDO($dsn, $user, $pass, $options);// 关闭自动提交,开启事务$pdo->beginTransaction();$sql1 = "INSERT INTO students (name, age, gender) VALUES ('小刚', 22, '男')";$sql2 = "INSERT INTO students (name, age, gender) VALUES ('小莉', 23, '女')";$pdo->exec($sql1);$pdo->exec($sql2);// 所有操作成功,提交事务$pdo->commit();echo "事务提交成功";
} catch (\PDOException $e) {// 捕获异常,回滚事务$pdo->rollBack();echo "事务回滚: ". $e->getMessage();
}
?>
4.2 预处理语句防止 SQL 注入及提高执行效率
4.2.1 SQL 注入原理
SQL 注入是一种常见的网络攻击方式,攻击者通过在输入参数中注入恶意的 SQL 语句,改变原 SQL 语句的逻辑,从而获取或篡改数据库中的数据。通常,Web 应用程序会接收用户的输入,并将其作为 SQL 语句的一部分执行。如果应用程序没有对用户输入进行充分的验证和过滤,攻击者就可以构造恶意的输入,使得 SQL 语句执行攻击者想要的操作。
例如,一个简单的用户登录验证代码:
<?php
$username = $_GET['username'];
$password = $_GET['password'];
$conn = new mysqli("localhost", "root", "", "test_db");
$sql = "SELECT * FROM users WHERE username = '$username' AND password = '$password'";
$result = $conn->query($sql);
if ($result->num_rows > 0) {echo "登录成功";
} else {echo "登录失败";
}
$conn->close();
?>
如果攻击者在username参数中输入admin’ OR ‘1’='1,密码随意输入,那么最终的 SQL 语句会变成:
SELECT * FROM users WHERE username = 'admin' OR '1'='1' AND password = '任意值'
由于’1’='1’恒为真,这样攻击者就可以绕过身份验证,成功登录系统。
4.2.2 预处理语句防止 SQL 注入和提高执行效率的原理
预处理语句(Prepared Statements)是数据库管理系统中一种用于优化数据库查询的技术,它允许将 SQL 语句从应用程序中分离出来,以一种能够被数据库高效执行的方式来准备和使用这些语句。
- 防止 SQL 注入:预处理语句通过参数化查询的方式,将 SQL 语句的结构和数据部分分开处理。在执行预处理语句时,参数的值会被数据库单独处理和检查,而不是直接嵌入到 SQL 语句中。这样,即使参数值中包含可能破坏 SQL 语句结构的特殊字符(如单引号),也不会影响 SQL 语句的逻辑,从而有效防止 SQL 注入攻击。
- 提高执行效率:常规 SQL 语句是直接发送到数据库,并在每次执行时被数据库解析和编译 。而预处理语句在第一次使用时就已经被编译,当语句再次执行时,数据库只需要执行编译过的预处理语句,而不必每次都进行解析和编译。这种优化可以显著提高执行效率,特别是对于那些频繁执行的查询。
4.2.3 代码示例
使用mysqli扩展的预处理语句示例:
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "test_db";// 创建连接
$conn = new mysqli($servername, $username, $password, $dbname);// 检查连接
if ($conn->connect_error) {die("连接失败: ". $conn->connect_error);
}$username = "admin";
$password = "123456";// 准备SQL语句
$stmt = $conn->prepare("SELECT * FROM users WHERE username =? AND password =?");
// 绑定参数
$stmt->bind_param("ss", $username, $password);
// 执行语句
$stmt->execute();
// 获取结果
$result = $stmt->get_result();if ($result->num_rows > 0) {echo "登录成功";
} else {echo "登录失败";
}// 关闭语句和连接
$stmt->close();
$conn->close();
?>
使用 PDO 的预处理语句示例:
<?php
$host = 'localhost';
$db = 'test_db';
$user = 'root';
$pass = '';
$charset = 'utf8mb4';$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,PDO::ATTR_EMULATE_PREPARES => false,
];try {$pdo = new PDO($dsn, $user, $pass, $options);$username = "admin";$password = "123456";$sql = "SELECT * FROM users WHERE username = :username AND password = :password";$stmt = $pdo->prepare($sql);$stmt->execute(['username' => $username,'password' => $password]);$result = $stmt->fetch();if ($result) {echo "登录成功";} else {echo "登录失败";}
} catch (\PDOException $e) {echo "Error: ". $e->getMessage();
}
?>
通过上述代码示例可以看到,预处理语句将用户输入的数据作为参数传递,而不是直接拼接到 SQL 语句中,从而有效防止了 SQL 注入攻击,同时提高了数据库操作的执行效率。在实际的 PHP 开发中,使用预处理语句进行数据库操作是非常重要的安全和性能优化措施。