# PHP与数据库交互:MySQL的常用操作分享
## 引言
在Web开发中,PHP与MySQL的组合堪称经典搭档。掌握PHP如何与MySQL数据库交互是每个PHP开发者必备的核心技能。本文将详细介绍PHP连接MySQL数据库的常用操作,从基础连接到增删改查,再到高级特性,帮助你构建更强大的数据库驱动应用。
## 一、连接MySQL数据库
### 1. 使用MySQLi扩展连接
```php
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "myDB";
// 创建连接
$conn = new mysqli($servername, $username, $password, $dbname);
// 检查连接
if ($conn->connect_error) {
die("连接失败: " . $conn->connect_error);
}
echo "连接成功";
?>
```
### 2. 使用PDO连接
```php
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "myDB";
try {
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
// 设置PDO错误模式为异常
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "连接成功";
}
catch(PDOException $e) {
echo "连接失败: " . $e->getMessage();
}
?>
```
## 二、基本CRUD操作
### 1. 创建数据表
```php
// 使用MySQLi
$sql = "CREATE TABLE users (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(30) NOT NULL,
email VARCHAR(50),
reg_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)";
if ($conn->query($sql) === TRUE) {
echo "表创建成功";
} else {
echo "错误: " . $conn->error;
}
```
### 2. 插入数据
```php
// 使用MySQLi
$sql = "INSERT INTO users (username, email) VALUES ('John', 'john@example.com')";
if ($conn->query($sql) === TRUE) {
echo "新记录插入成功";
} else {
echo "错误: " . $sql . "<br>" . $conn->error;
}
// 使用PDO预处理语句
$stmt = $conn->prepare("INSERT INTO users (username, email) VALUES (:username, :email)");
$stmt->bindParam(':username', $username);
$stmt->bindParam(':email', $email);
$username = "Jane";
$email = "jane@example.com";
$stmt->execute();
```
### 3. 查询数据
```php
// 使用MySQLi
$sql = "SELECT id, username, email FROM users";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
echo "id: " . $row["id"]. " - Name: " . $row["username"]. " - Email: " . $row["email"]. "<br>";
}
} else {
echo "0 结果";
}
// 使用PDO
$stmt = $conn->prepare("SELECT id, username, email FROM users");
$stmt->execute();
// 设置结果集为关联数组
$result = $stmt->setFetchMode(PDO::FETCH_ASSOC);
foreach($stmt->fetchAll() as $row) {
echo "id: " . $row["id"]. " - Name: " . $row["username"]. " - Email: " . $row["email"]. "<br>";
}
```
### 4. 更新数据
```php
// 使用MySQLi
$sql = "UPDATE users SET email='john.doe@example.com' WHERE id=1";
if ($conn->query($sql) === TRUE) {
echo "记录更新成功";
} else {
echo "更新错误: " . $conn->error;
}
// 使用PDO
$stmt = $conn->prepare("UPDATE users SET email = :email WHERE id = :id");
$stmt->bindParam(':email', $email);
$stmt->bindParam(':id', $id);
$email = "newemail@example.com";
$id = 1;
$stmt->execute();
```
### 5. 删除数据
```php
// 使用MySQLi
$sql = "DELETE FROM users WHERE id=1";
if ($conn->query($sql) === TRUE) {
echo "记录删除成功";
} else {
echo "删除错误: " . $conn->error;
}
// 使用PDO
$stmt = $conn->prepare("DELETE FROM users WHERE id = :id");
$stmt->bindParam(':id', $id);
$id = 2;
$stmt->execute();
```
## 三、高级操作技巧
### 1. 预处理语句与防SQL注入
```php
// MySQLi预处理
$stmt = $conn->prepare("INSERT INTO users (username, email) VALUES (?, ?)");
$stmt->bind_param("ss", $username, $email);
$username = "Alice";
$email = "alice@example.com";
$stmt->execute();
// PDO预处理
$stmt = $conn->prepare("SELECT * FROM users WHERE username = :username");
$stmt->bindParam(':username', $username);
$username = "Alice";
$stmt->execute();
$result = $stmt->fetchAll();
```
### 2. 事务处理
```php
// MySQLi事务
$conn->autocommit(FALSE);
$conn->query("INSERT INTO users (username, email) VALUES ('Tom', 'tom@example.com')");
$conn->query("INSERT INTO orders (user_id, product) VALUES (LAST_INSERT_ID(), 'Laptop')");
if($conn->commit()) {
echo "事务提交成功";
} else {
$conn->rollback();
echo "事务失败,已回滚";
}
// PDO事务
try {
$conn->beginTransaction();
$conn->exec("INSERT INTO users (username, email) VALUES ('Tom', 'tom@example.com')");
$conn->exec("INSERT INTO orders (user_id, product) VALUES (LAST_INSERT_ID(), 'Laptop')");
$conn->commit();
echo "事务提交成功";
} catch(Exception $e) {
$conn->rollback();
echo "事务失败: " . $e->getMessage();
}
```
### 3. 分页查询
```php
$results_per_page = 5;
// 获取总页数
$sql = "SELECT COUNT(*) AS total FROM users";
$result = $conn->query($sql);
$row = $result->fetch_assoc();
$number_of_pages = ceil($row["total"] / $results_per_page);
// 获取当前页数据
if (!isset($_GET['page'])) {
$page = 1;
} else {
$page = $_GET['page'];
}
$page_first_result = ($page-1) * $results_per_page;
$sql = "SELECT * FROM users LIMIT " . $page_first_result . "," . $results_per_page;
$result = $conn->query($sql);
while($row = $result->fetch_assoc()) {
// 显示数据
}
// 显示分页链接
for ($page=1; $page<=$number_of_pages; $page++) {
echo '<a href="index.php?page=' . $page . '">' . $page . '</a> ';
}
```
## 四、性能优化建议
1. **使用持久连接**:对于高流量应用,可以考虑使用持久连接减少连接开销
```php
$conn = new mysqli('p:' . $servername, $username, $password, $dbname);
```
2. **合理使用索引**:确保查询条件中的字段有适当的索引
3. **批量操作**:使用批量插入代替多次单条插入
```php
$sql = "INSERT INTO users (username, email) VALUES
('user1', 'user1@example.com'),
('user2', 'user2@example.com'),
('user3', 'user3@example.com')";
```
4. **缓存查询结果**:对于不频繁变化的数据,考虑使用缓存机制
5. **选择合适的数据类型**:使用最合适的数据类型可以减少存储空间和提高查询效率
## 五、常见问题解答
**Q:MySQLi和PDO有什么区别?**
A:MySQLi是MySQL专用的扩展,只支持MySQL数据库;PDO支持多种数据库,提供更统一的API。PDO通常被认为更加灵活和安全,特别是在预处理语句方面。
**Q:如何防止SQL注入?**
A:务必使用预处理语句(如上文所示),永远不要直接将用户输入拼接到SQL查询中。
**Q:连接数据库失败怎么办?**
A:检查:
1. 数据库服务器是否运行
2. 连接参数是否正确
3. 用户是否有权限
4. 网络连接是否正常
5. 错误日志中是否有更多信息
## 结语
掌握PHP与MySQL的交互是Web开发的基础技能。本文涵盖了从基础连接到高级操作的方方面面,希望能为你的开发工作提供帮助。在实际开发中,记得遵循安全最佳实践,合理优化数据库操作,才能构建出高效、安全的应用程序。
如果你有任何问题或想了解更多内容,欢迎在评论区留言交流!