在PHP中访问数据库是开发动态网站的核心技能之一,无论是存储用户数据、管理内容还是处理交易,数据库交互都至关重要,以下是详细的操作指南,涵盖主流方法、安全实践和最佳方案:
PHP访问数据库的两种主流方式
-
MySQLi (MySQL Improved)
- 优势:专为MySQL设计,支持面向对象和面向过程两种写法,性能高效。
- 适用场景:仅需操作MySQL/MariaDB数据库时。
- 支持特性:预处理语句、事务操作、多语句查询。
-
PDO (PHP Data Objects)
- 优势:支持12+种数据库(如MySQL、PostgreSQL、SQLite),接口统一,迁移成本低。
- 适用场景:需兼容多种数据库或未来可能切换数据库时。
- 支持特性:命名参数、错误处理更灵活、预处理语句。
详细操作步骤(含安全实践)
连接数据库
// MySQLi (面向对象) $servername = "localhost"; $username = "your_username"; $password = "your_password"; $dbname = "your_db"; $conn = new mysqli($servername, $username, $password, $dbname); if ($conn->connect_error) { die("连接失败: " . $conn->connect_error); } // PDO (通用方法) try { $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password); $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // 启用错误异常 } catch(PDOException $e) { die("连接失败: " . $e->getMessage()); }
执行查询与获取数据(使用预处理防SQL注入)
示例:查询用户数据
$user_id = 1; // 用户输入值 // MySQLi 预处理 $stmt = $conn->prepare("SELECT name, email FROM users WHERE id = ?"); $stmt->bind_param("i", $user_id); // "i"表示整数类型 $stmt->execute(); $result = $stmt->get_result(); while ($row = $result->fetch_assoc()) { echo "姓名: " . $row['name'] . ", 邮箱: " . $row['email']; } // PDO 预处理 $stmt = $conn->prepare("SELECT name, email FROM users WHERE id = :id"); $stmt->bindParam(':id', $user_id, PDO::PARAM_INT); // 指定参数类型 $stmt->execute(); while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { echo "姓名: " . $row['name'] . ", 邮箱: " . $row['email']; }
插入/更新数据
$name = "张三"; $email = "zhangsan@example.com"; // MySQLi 插入 $stmt = $conn->prepare("INSERT INTO users (name, email) VALUES (?, ?)"); $stmt->bind_param("ss", $name, $email); // "ss"表示两个字符串 $stmt->execute(); // PDO 插入 $stmt = $conn->prepare("INSERT INTO users (name, email) VALUES (:name, :email)"); $stmt->execute([':name' => $name, ':email' => $email]);
关闭连接
// MySQLi $conn->close(); // PDO $conn = null;
关键安全措施
-
必须使用预处理语句
- 避免直接拼接SQL(如
"SELECT * FROM users WHERE id = $id"
),防止SQL注入攻击。 - 预处理通过参数绑定分离指令与数据,彻底杜绝恶意输入破坏查询结构。
- 避免直接拼接SQL(如
-
错误处理原则
- 生产环境禁用
display_errors
,防止泄露数据库信息。 - 开发阶段启用详细错误日志(PDO推荐
PDO::ERRMODE_EXCEPTION
)。
- 生产环境禁用
-
最小权限原则
数据库账户仅授予必要权限(如禁止DROP操作)。
选型建议
- 优先选择PDO:
跨数据库兼容性、命名参数更直观、错误处理机制更完善。 - 选MySQLi的场景:
仅需MySQL高级特性(如异步查询)或维护旧项目。
常见问题排查
- 连接失败:检查端口(默认3306)、防火墙、用户名/密码。
- 查询无结果:用
try/catch
捕获异常,或检查SQL语法(如$stmt->errorInfo()
)。 - 性能优化:长连接(
mysqli
的p:
前缀)、复用预处理语句。
PHP访问数据库的核心是预处理语句 + 参数绑定,这是安全性的基石,PDO因其灵活性和扩展性成为现代PHP项目的首选,而MySQLi在纯MySQL环境中性能稍优,无论选择哪种方式,始终遵循:
- 绝不信任用户输入
- 明确错误日志与生产环境隔离
- 按需释放连接资源
掌握这些实践,可构建高效且安全的数据库交互层。
引用说明基于PHP官方文档(php.net)的安全规范及数据库操作指南,并结合OWASP SQL注入防护建议编写,代码示例遵循PSR-12编码标准,已在PHP 7.4+环境测试通过。
原创文章,发布者:酷盾叔,转转请注明出处:https://www.kd.cn/ask/28008.html