上一篇
php 数据库怎么写
- 数据库
- 2025-07-23
- 4
使用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专项