🐘 MySQL PHP 语法
PHP 是最常用的 Web 开发语言之一,与 MySQL 数据库的集成非常紧密。本章将介绍如何在 PHP 中连接和操作 MySQL 数据库。
📊 PHP MySQL 连接方法对比
方法 |
MySQL 5.7 |
MySQL 8.x |
推荐度 |
MySQLi |
✅ 支持 |
✅ 支持 |
⭐⭐⭐⭐ |
PDO |
✅ 支持 |
✅ 支持 |
⭐⭐⭐⭐⭐ |
MySQL (已废弃) |
❌ 已移除 |
❌ 不支持 |
❌ 不推荐 |
🔗 PDO 连接方式(推荐)
基本连接
<?php
// PDO 连接 MySQL 数据库
$host = 'localhost';
$dbname = 'test_db';
$username = 'root';
$password = 'your_password';
try {
// MySQL 8.x 连接字符串
$dsn = "mysql:host=$host;dbname=$dbname;charset=utf8mb4";
$pdo = new PDO($dsn, $username, $password, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
]);
echo "数据库连接成功!";
} catch (PDOException $e) {
die("连接失败: " . $e->getMessage());
}
?>
MySQL 8.x 连接注意事项
MySQL 8.x 默认使用 caching_sha2_password
认证插件。如果遇到连接问题,可能需要:
- 升级 PHP 到 7.2.4+ 版本
- 或者修改 MySQL 用户认证方式为
mysql_native_password
创建数据库和表
<?php
// 创建数据库
$sql_create_db = "CREATE DATABASE IF NOT EXISTS test_db
CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci";
$pdo->exec($sql_create_db);
// 使用数据库
$pdo->exec("USE test_db");
// 创建用户表
$sql_create_table = "
CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
email VARCHAR(100) NOT NULL,
password VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci";
$pdo->exec($sql_create_table);
echo "表创建成功!";
?>
插入数据(预处理语句)
<?php
// 插入单条数据
function insertUser($pdo, $username, $email, $password) {
$sql = "INSERT INTO users (username, email, password) VALUES (?, ?, ?)";
$stmt = $pdo->prepare($sql);
// 密码加密
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
return $stmt->execute([$username, $email, $hashed_password]);
}
// 使用示例
try {
insertUser($pdo, 'john_doe', 'john@example.com', 'secure123');
echo "用户插入成功!";
} catch (PDOException $e) {
echo "插入失败: " . $e->getMessage();
}
// 批量插入
function insertMultipleUsers($pdo, $users) {
$sql = "INSERT INTO users (username, email, password) VALUES (?, ?, ?)";
$stmt = $pdo->prepare($sql);
$pdo->beginTransaction();
try {
foreach ($users as $user) {
$hashed_password = password_hash($user['password'], PASSWORD_DEFAULT);
$stmt->execute([$user['username'], $user['email'], $hashed_password]);
}
$pdo->commit();
return true;
} catch (Exception $e) {
$pdo->rollback();
throw $e;
}
}
?>
查询数据
<?php
// 查询所有用户
function getAllUsers($pdo) {
$sql = "SELECT id, username, email, created_at FROM users ORDER BY created_at DESC";
$stmt = $pdo->query($sql);
return $stmt->fetchAll();
}
// 根据ID查询用户
function getUserById($pdo, $id) {
$sql = "SELECT id, username, email, created_at FROM users WHERE id = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$id]);
return $stmt->fetch();
}
// 分页查询
function getUsersPaginated($pdo, $page = 1, $limit = 10) {
$offset = ($page - 1) * $limit;
$sql = "SELECT id, username, email, created_at FROM users
ORDER BY created_at DESC LIMIT ? OFFSET ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$limit, $offset]);
return $stmt->fetchAll();
}
// 搜索用户
function searchUsers($pdo, $keyword) {
$sql = "SELECT id, username, email, created_at FROM users
WHERE username LIKE ? OR email LIKE ?";
$stmt = $pdo->prepare($sql);
$searchTerm = "%$keyword%";
$stmt->execute([$searchTerm, $searchTerm]);
return $stmt->fetchAll();
}
// 使用示例
$users = getAllUsers($pdo);
foreach ($users as $user) {
echo "用户: " . $user['username'] . " - " . $user['email'] . "\n";
}
?>
更新和删除数据
<?php
// 更新用户信息
function updateUser($pdo, $id, $username, $email) {
$sql = "UPDATE users SET username = ?, email = ? WHERE id = ?";
$stmt = $pdo->prepare($sql);
return $stmt->execute([$username, $email, $id]);
}
// 更新密码
function updatePassword($pdo, $id, $new_password) {
$sql = "UPDATE users SET password = ? WHERE id = ?";
$stmt = $pdo->prepare($sql);
$hashed_password = password_hash($new_password, PASSWORD_DEFAULT);
return $stmt->execute([$hashed_password, $id]);
}
// 删除用户
function deleteUser($pdo, $id) {
$sql = "DELETE FROM users WHERE id = ?";
$stmt = $pdo->prepare($sql);
return $stmt->execute([$id]);
}
// 软删除(推荐)
function softDeleteUser($pdo, $id) {
$sql = "UPDATE users SET deleted_at = CURRENT_TIMESTAMP WHERE id = ?";
$stmt = $pdo->prepare($sql);
return $stmt->execute([$id]);
}
?>
🔧 MySQLi 连接方式
面向对象方式
<?php
// MySQLi 面向对象连接
$host = 'localhost';
$username = 'root';
$password = 'your_password';
$database = 'test_db';
$mysqli = new mysqli($host, $username, $password, $database);
// 检查连接
if ($mysqli->connect_error) {
die('连接失败: ' . $mysqli->connect_error);
}
// 设置字符集(重要!)
$mysqli->set_charset("utf8mb4");
echo "MySQLi 连接成功!";
// 查询示例
$sql = "SELECT id, username, email FROM users";
$result = $mysqli->query($sql);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
echo "ID: " . $row["id"]. " - 用户名: " . $row["username"]. " - 邮箱: " . $row["email"]. "\n";
}
} else {
echo "0 结果";
}
$mysqli->close();
?>
预处理语句(MySQLi)
<?php
// MySQLi 预处理语句
function insertUserMySQLi($mysqli, $username, $email, $password) {
$sql = "INSERT INTO users (username, email, password) VALUES (?, ?, ?)";
$stmt = $mysqli->prepare($sql);
if ($stmt) {
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
$stmt->bind_param("sss", $username, $email, $hashed_password);
if ($stmt->execute()) {
echo "新记录插入成功";
return $mysqli->insert_id; // 返回插入的ID
} else {
echo "Error: " . $stmt->error;
}
$stmt->close();
}
}
// 查询预处理语句
function getUserByIdMySQLi($mysqli, $id) {
$sql = "SELECT id, username, email, created_at FROM users WHERE id = ?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param("i", $id);
$stmt->execute();
$result = $stmt->get_result();
$user = $result->fetch_assoc();
$stmt->close();
return $user;
}
?>
🔒 安全最佳实践
1. 防止 SQL 注入
<?php
// ❌ 错误示例 - 容易受到 SQL 注入攻击
$username = $_POST['username'];
$sql = "SELECT * FROM users WHERE username = '$username'";
// ✅ 正确示例 - 使用预处理语句
$username = $_POST['username'];
$sql = "SELECT * FROM users WHERE username = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$username]);
?>
2. 密码安全处理
<?php
// 密码加密
function hashPassword($password) {
return password_hash($password, PASSWORD_DEFAULT);
}
// 密码验证
function verifyPassword($password, $hash) {
return password_verify($password, $hash);
}
// 登录验证示例
function authenticateUser($pdo, $username, $password) {
$sql = "SELECT id, username, password FROM users WHERE username = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$username]);
$user = $stmt->fetch();
if ($user && password_verify($password, $user['password'])) {
return $user;
}
return false;
}
?>
3. 错误处理
<?php
// 生产环境错误处理
try {
$pdo = new PDO($dsn, $username, $password, $options);
} catch (PDOException $e) {
// 记录错误日志,不要直接显示给用户
error_log("数据库连接失败: " . $e->getMessage());
die("系统暂时不可用,请稍后再试");
}
// 开发环境可以显示详细错误
if (ENVIRONMENT === 'development') {
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
?>
🚀 MySQL 8.x 特性在 PHP 中的应用
JSON 数据处理
<?php
// 创建包含 JSON 字段的表
$sql = "CREATE TABLE IF NOT EXISTS user_profiles (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT,
profile JSON,
settings JSON
)";
$pdo->exec($sql);
// 插入 JSON 数据
function insertUserProfile($pdo, $user_id, $profile, $settings) {
$sql = "INSERT INTO user_profiles (user_id, profile, settings) VALUES (?, ?, ?)";
$stmt = $pdo->prepare($sql);
return $stmt->execute([
$user_id,
json_encode($profile),
json_encode($settings)
]);
}
// 查询 JSON 数据
function getUserProfile($pdo, $user_id) {
$sql = "SELECT profile->>'$.name' as name,
profile->>'$.age' as age,
settings->>'$.theme' as theme
FROM user_profiles WHERE user_id = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$user_id]);
return $stmt->fetch();
}
// 使用示例
$profile = ['name' => '张三', 'age' => 25, 'city' => '北京'];
$settings = ['theme' => 'dark', 'language' => 'zh-CN'];
insertUserProfile($pdo, 1, $profile, $settings);
?>
窗口函数应用
<?php
// MySQL 8.x 窗口函数示例
function getUserRanking($pdo) {
$sql = "SELECT username,
score,
ROW_NUMBER() OVER (ORDER BY score DESC) as ranking,
RANK() OVER (ORDER BY score DESC) as rank_with_ties
FROM user_scores
ORDER BY score DESC";
$stmt = $pdo->query($sql);
return $stmt->fetchAll();
}
// 分组排名
function getDepartmentRanking($pdo) {
$sql = "SELECT department,
username,
salary,
ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) as dept_rank
FROM employees
ORDER BY department, salary DESC";
$stmt = $pdo->query($sql);
return $stmt->fetchAll();
}
?>
📋 完整示例:用户管理系统
<?php
class UserManager {
private $pdo;
public function __construct($pdo) {
$this->pdo = $pdo;
}
// 创建用户
public function createUser($username, $email, $password) {
$sql = "INSERT INTO users (username, email, password) VALUES (?, ?, ?)";
$stmt = $this->pdo->prepare($sql);
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
return $stmt->execute([$username, $email, $hashed_password]);
}
// 获取用户列表
public function getUsers($page = 1, $limit = 10) {
$offset = ($page - 1) * $limit;
$sql = "SELECT id, username, email, created_at FROM users
ORDER BY created_at DESC LIMIT ? OFFSET ?";
$stmt = $this->pdo->prepare($sql);
$stmt->execute([$limit, $offset]);
return $stmt->fetchAll();
}
// 用户认证
public function authenticate($username, $password) {
$sql = "SELECT id, username, password FROM users WHERE username = ?";
$stmt = $this->pdo->prepare($sql);
$stmt->execute([$username]);
$user = $stmt->fetch();
if ($user && password_verify($password, $user['password'])) {
unset($user['password']); // 移除密码字段
return $user;
}
return false;
}
}
// 使用示例
$userManager = new UserManager($pdo);
$userManager->createUser('admin', 'admin@example.com', 'admin123');
$users = $userManager->getUsers();
?>