上一篇
php 数据库怎么写
- 数据库
- 2025-07-23
- 4227
使用PDO或mysqli扩展连接数据库,通过prepare/bind/execute执行SQL语句,结合try-catch处理异常,注意参数化查询
在PHP中实现数据库操作是Web开发的核心技能之一,以下是详细的技术指南,涵盖从环境配置到安全防护的全流程:
数据库操作基础架构
| 操作环节 | 关键技术点 | 推荐扩展 |
|---|---|---|
| 连接数据库 | 主机名/IP、用户名、密码、端口 | PDO(支持多数据库)、mysqli(MySQL专属) |
| 数据定义 | SQL语法(CREATE TABLE) | MySQL Workbench(可视化工具) |
| 数据处理 | CRUD操作(增删改查) | PDO::prepare()/mysqli_prepare() |
| 安全防护 | 参数化查询、输入验证 | 过滤器(filter_input()) |
标准化实现流程
数据库连接配置
(1)PDO扩展实现(推荐)
// config.php
$dsn = 'mysql:host=localhost;dbname=test_db;charset=utf8';
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // 开启异常模式
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // 关联数组返回
];
try {
$pdo = new PDO($dsn, 'root', 'password', $options);
} catch (PDOException $e) {
error_log('数据库连接失败: ' . $e->getMessage());
die('系统错误,请联系管理员');
}
优势:支持12种数据库(MySQL/PostgreSQL/SQLite等),统一的接口设计。
(2)mysqli扩展实现
// config.php
$mysqli = new mysqli("localhost", "root", "password", "test_db");
if ($mysqli->connect_error) {
error_log("连接失败: " . $mysqli->connect_error);
die("数据库连接异常");
}
$mysqli->set_charset("utf8mb4"); // 设置字符编码
适用场景:专为MySQL优化,性能更优。
数据结构设计
(1)规范化命名规则
- 表名采用小写字母+下划线分隔(如user_info)
- 字段名避免使用保留字(如order改为order_no)
- 主键建议命名为id,自增属性
(2)创建数据表示例

CREATE TABLE `users` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, `username` VARCHAR(50) NOT NULL UNIQUE, `password` VARCHAR(255) NOT NULL, `email` VARCHAR(100) NOT NULL, `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CRUD操作实现
(1)插入数据(Insert)
// 使用PDO
$stmt = $pdo->prepare("INSERT INTO users (username, password, email) VALUES (?, ?, ?)");
$stmt->execute([$username, $hashedPassword, $email]);
// 使用mysqli
$stmt = $mysqli->prepare("INSERT INTO users (username, password, email) VALUES (?, ?, ?)");
$stmt->bind_param("sss", $username, $hashedPassword, $email);
$stmt->execute();
(2)查询数据(Select)
// 单条查询
$stmt = $pdo->prepare("SELECT FROM users WHERE id = ?");
$stmt->execute([$userId]);
$user = $stmt->fetch();
// 多条查询
$stmt = $mysqli->prepare("SELECT username, email FROM users WHERE status = ?");
$stmt->bind_param("s", $status);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
// 处理数据
}
(3)更新数据(Update)
// PDO方式
$stmt = $pdo->prepare("UPDATE users SET email = :email WHERE id = :id");
$stmt->execute(['email' => $newEmail, 'id' => $userId]);
// mysqli方式
$stmt = $mysqli->prepare("UPDATE users SET email = ? WHERE id = ?");
$stmt->bind_param("si", $newEmail, $userId);
$stmt->execute();
(4)删除数据(Delete)
// PDO事务删除
$pdo->beginTransaction();
try {
$stmt = $pdo->prepare("DELETE FROM users WHERE id = ?");
$stmt->execute([$userId]);
$pdo->commit();
} catch (Exception $e) {
$pdo->rollBack();
throw $e;
}
安全防护机制
-
参数化查询防注入
对比两种风险写法:
- 不安全写法(SQL注入风险):
$username = $_POST['username']; $sql = "SELECT FROM users WHERE username = '$username'"; // 存在注入风险
- 安全写法(预处理语句):
$stmt = $mysqli->prepare("SELECT FROM users WHERE username = ?"); $stmt->bind_param("s", $username); $stmt->execute();
- 不安全写法(SQL注入风险):
-
输入验证与过滤
// 后端二次验证 $email = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL); if (!$email) { exit('无效的邮箱格式'); } -
权限控制原则
- 生产环境禁用root账号
- 按最小权限原则分配用户权限(如只授予SELECT/INSERT权限)
- 使用SSL加密数据库连接(特别是远程连接时)
错误处理规范
| 扩展类型 | 错误检测方式 | 最佳实践 |
|---|---|---|
| PDO | try-catch捕获异常 | 记录错误日志,返回通用错误信息 |
| mysqli | 检查error属性 |
启用mysqli::sqlstate获取标准错误码 |
示例代码:
// PDO错误处理
try {
$pdo->exec("INVALID_SQL");
} catch (PDOException $e) {
error_log("PDO Error: " . $e->getMessage());
echo "执行数据库操作时发生错误";
}
// mysqli错误处理
if (!$mysqli->query("INVALID_SQL")) {
error_log("MySQL Error: " . $mysqli->error);
echo "数据库操作失败";
}
进阶优化策略
-
事务处理
// BEGIN TRANSACTION $pdo->beginTransaction(); try { // 多个操作... $pdo->commit(); } catch (Exception $e) { $pdo->rollBack(); throw $e; } -
批量操作

// 批量插入 $stmt = $pdo->prepare("INSERT INTO logs (message) VALUES (?)"); foreach ($messages as $msg) { $stmt->execute([$msg]); } -
分页查询
// 带偏移量的分页 $page = intval($_GET['page']) ?: 1; $perPage = 20; $offset = ($page 1) $perPage; $stmt = $mysqli->prepare("SELECT FROM articles LIMIT ? OFFSET ?"); $stmt->bind_param("ii", $perPage, $offset); $stmt->execute();
相关问答FAQs
Q1:如何解决中文乱码问题?
A1:在三个关键环节设置字符集:
- 连接数据库时指定charset=utf8mb4(PDO的DSN参数或mysqli的set_charset方法)
- HTML页面声明
<meta charset="UTF-8"> - 数据库表默认字符集设置为utf8mb4
Q2:如何有效防止SQL注入攻击?
A2:三级防护体系:
- 使用预处理语句绑定参数
- 对用户输入进行强制类型转换(如intval()处理ID)
- 添加WAF(Web应用防火墙)进行请求过滤
涵盖了从基础连接到安全防护的完整知识体系,建议开发者根据项目需求选择PDO(多数据库支持)或mysqli(MySQL专项
