PHP数据库访问的分层设计是指将数据库相关的操作按照职责拆分到不同的层级中,避免业务逻辑和数据库操作过度耦合,让代码结构更清晰,后续维护和扩展更方便。常见的分层结构包含模型层、数据访问对象层、服务层,各层各司其职,降低模块间的依赖。

分层设计的核心层级说明
模型层(Model)
模型层用于定义数据实体的结构,对应数据库中的表字段,通常只包含属性的定义和简单的 getter、setter 方法,不包含复杂的业务逻辑和数据库操作。
<?php
/**
* 用户模型类,对应users表
*/
class UserModel {
private $id;
private $username;
private $email;
public function getId() {
return $this->id;
}
public function setId($id) {
$this->id = $id;
}
public function getUsername() {
return $this->username;
}
public function setUsername($username) {
$this->username = $username;
}
public function getEmail() {
return $this->email;
}
public function setEmail($email) {
$this->email = $email;
}
}
?>
数据访问对象层(DAO)
DAO层专门负责和数据库进行交互,所有的增删改查操作都封装在这一层,上层只需要调用对应的方法,不需要关心具体的SQL语句和数据库连接细节。
<?php
/**
* 用户数据访问对象类
*/
class UserDao {
private $pdo;
public function __construct($pdo) {
$this->pdo = $pdo;
}
/**
* 根据ID查询用户
* @param int $id 用户ID
* @return UserModel|null
*/
public function getUserById($id) {
$sql = "SELECT id, username, email FROM users WHERE id = :id";
$stmt = $this->pdo->prepare($sql);
$stmt->execute([':id' => $id]);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$row) {
return null;
}
$user = new UserModel();
$user->setId($row['id']);
$user->setUsername($row['username']);
$user->setEmail($row['email']);
return $user;
}
/**
* 新增用户
* @param UserModel $user 用户对象
* @return int 新增的用户ID
*/
public function addUser(UserModel $user) {
$sql = "INSERT INTO users (username, email) VALUES (:username, :email)";
$stmt = $this->pdo->prepare($sql);
$stmt->execute([
':username' => $user->getUsername(),
':email' => $user->getEmail()
]);
return $this->pdo->lastInsertId();
}
}
?>
服务层(Service)
服务层负责处理业务逻辑,调用DAO层的方法完成数据操作,同时可以在这一层添加业务校验、事务处理等逻辑,隔离业务逻辑和数据库操作。
<?php
/**
* 用户服务类
*/
class UserService {
private $userDao;
public function __construct(UserDao $userDao) {
$this->userDao = $userDao;
}
/**
* 获取用户详情并做简单校验
* @param int $id 用户ID
* @return UserModel|null
*/
public function getUserDetail($id) {
if ($id <= 0) {
return null;
}
return $this->userDao->getUserById($id);
}
/**
* 创建新用户
* @param string $username 用户名
* @param string $email 邮箱
* @return int 新增用户ID
*/
public function createUser($username, $email) {
if (empty($username) || empty($email)) {
throw new InvalidArgumentException("用户名和邮箱不能为空");
}
$user = new UserModel();
$user->setUsername($username);
$user->setEmail($email);
return $this->userDao->addUser($user);
}
}
?>
分层设计的调用流程示例
在实际的业务入口中,只需要初始化对应的对象,调用服务层的方法即可,不需要直接接触数据库操作代码。
<?php
// 初始化数据库连接
$pdo = new PDO("mysql:host=127.0.0.1;dbname=test;charset=utf8", "root", "123456");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// 初始化各层对象
$userDao = new UserDao($pdo);
$userService = new UserService($userDao);
// 调用服务层方法获取用户
$user = $userService->getUserDetail(1);
if ($user) {
echo "用户名:" . $user->getUsername() . ",邮箱:" . $user->getEmail();
} else {
echo "用户不存在";
}
// 调用服务层方法创建用户
try {
$newUserId = $userService->createUser("test_user", "test@ipipp.com");
echo "新增用户ID:" . $newUserId;
} catch (Exception $e) {
echo "创建用户失败:" . $e->getMessage();
}
?>
分层设计的优势
- 降低耦合度:业务逻辑和数据库操作分离,修改数据库操作不会影响业务逻辑代码
- 提升可维护性:各层职责清晰,出现问题可以快速定位到对应的层级
- 便于扩展:如果需要更换数据库类型,只需要修改DAO层的实现即可,上层代码不需要改动
- 代码复用性高:DAO层的通用方法可以被多个服务层复用,减少重复代码
注意:分层设计并不是层级越多越好,小型项目可以根据实际情况简化层级,避免过度设计导致代码复杂度上升。