PHP 怎么PHP 数据映射

wen PHP项目 1

本文目录导读:

PHP 怎么PHP 数据映射

  1. 什么是数据映射模式
  2. 基本实现方式
  3. 数据映射的优点
  4. 常见的PHP数据映射框架

我来详细解释PHP中的数据映射(Data Mapping)模式:

什么是数据映射模式

数据映射器是一种架构模式,用于在对象和数据库之间进行双向数据转换,让对象和数据库结构保持独立。

基本实现方式

基础数据映射器示例

<?php
// 实体类
class User {
    private $id;
    private $name;
    private $email;
    public function __construct($id = null, $name = null, $email = null) {
        $this->id = $id;
        $this->name = $name;
        $this->email = $email;
    }
    // Getters and Setters
    public function getId() { return $this->id; }
    public function getName() { return $this->name; }
    public function setName($name) { $this->name = $name; }
    public function getEmail() { return $this->email; }
    public function setEmail($email) { $this->email = $email; }
}
// 数据映射器
class UserMapper {
    private $db;
    public function __construct(PDO $db) {
        $this->db = $db;
    }
    // 从数据库加载对象
    public function find($id) {
        $stmt = $this->db->prepare("SELECT * FROM users WHERE id = ?");
        $stmt->execute([$id]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        if (!$row) return null;
        return new User(
            $row['id'],
            $row['name'],
            $row['email']
        );
    }
    // 保存对象到数据库
    public function save(User $user) {
        if ($user->getId()) {
            // 更新
            $stmt = $this->db->prepare("UPDATE users SET name=?, email=? WHERE id=?");
            $stmt->execute([
                $user->getName(),
                $user->getEmail(),
                $user->getId()
            ]);
        } else {
            // 插入
            $stmt = $this->db->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
            $stmt->execute([
                $user->getName(),
                $user->getEmail()
            ]);
            $user->setId($this->db->lastInsertId());
        }
    }
    // 删除对象
    public function delete(User $user) {
        $stmt = $this->db->prepare("DELETE FROM users WHERE id = ?");
        $stmt->execute([$user->getId()]);
    }
}

使用示例

<?php
// 使用数据映射器
$pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'password');
$userMapper = new UserMapper($pdo);
// 查找用户
$user = $userMapper->find(1);
echo $user->getName();
// 修改用户
$user->setName('New Name');
$userMapper->save($user);
// 创建新用户
$newUser = new User(null, 'John', 'john@example.com');
$userMapper->save($newUser);
// 删除用户
$userMapper->delete($user);

高级数据映射器模式

<?php
// 抽象映射器
abstract class AbstractMapper {
    protected $db;
    protected $table;
    public function __construct(PDO $db, $table) {
        $this->db = $db;
        $this->table = $table;
    }
    public function find($id) {
        $stmt = $this->db->prepare("SELECT * FROM {$this->table} WHERE id = ?");
        $stmt->execute([$id]);
        return $this->mapRowToObject($stmt->fetch(PDO::FETCH_ASSOC));
    }
    public function findAll() {
        $stmt = $this->db->query("SELECT * FROM {$this->table}");
        $objects = [];
        while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
            $objects[] = $this->mapRowToObject($row);
        }
        return $objects;
    }
    abstract protected function mapRowToObject($row);
    abstract protected function mapObjectToRow($object);
    public function save($object) {
        $row = $this->mapObjectToRow($object);
        if ($object->getId()) {
            $this->update($row, $object->getId());
        } else {
            $this->insert($row);
            $object->setId($this->db->lastInsertId());
        }
    }
    private function insert($row) {
        $columns = implode(', ', array_keys($row));
        $placeholders = implode(', ', array_fill(0, count($row), '?'));
        $stmt = $this->db->prepare("INSERT INTO {$this->table} ($columns) VALUES ($placeholders)");
        $stmt->execute(array_values($row));
    }
    private function update($row, $id) {
        $sets = implode('=?, ', array_keys($row)) . '=?';
        $values = array_values($row);
        $values[] = $id;
        $stmt = $this->db->prepare("UPDATE {$this->table} SET $sets WHERE id=?");
        $stmt->execute($values);
    }
}
// 具体实现
class ProductMapper extends AbstractMapper {
    public function __construct(PDO $db) {
        parent::__construct($db, 'products');
    }
    protected function mapRowToObject($row) {
        if (!$row) return null;
        return new Product(
            $row['id'],
            $row['name'],
            $row['price'],
            $row['category_id']
        );
    }
    protected function mapObjectToRow($object) {
        return [
            'name' => $object->getName(),
            'price' => $object->getPrice(),
            'category_id' => $object->getCategoryId()
        ];
    }
}

使用Doctrine ORM(流行的PHP数据映射工具)

<?php
// 使用Doctrine ORM
use Doctrine\ORM\Mapping as ORM;
/**
 * @ORM\Entity
 * @ORM\Table(name="users")
 */
class User {
    /** @ORM\Id @ORM\Column(type="integer") @ORM\GeneratedValue */
    private $id;
    /** @ORM\Column(type="string") */
    private $name;
    /** @ORM\Column(type="string", unique=true) */
    private $email;
    // Getters and setters...
}
// 使用
$user = $entityManager->find('User', 1);
$user->setName('New Name');
$entityManager->flush();

数据映射的优点

  1. 分离关注点 - 业务逻辑与数据访问分离
  2. 测试便利 - 可以独立测试实体和映射器
  3. 灵活性 - 可以更改数据库结构而不影响业务代码
  4. 重用性 - 映射器可以在不同地方重用

常见的PHP数据映射框架

  • Doctrine ORM - 最流行的PHP ORM
  • Eloquent ORM - Laravel的ORM
  • Propel - 另一个流行的ORM
  • RedBeanPHP - 零配置ORM

数据映射模式在处理复杂的数据关系时特别有用,能帮助你保持代码的清洁和可维护性。

抱歉,评论功能暂时关闭!