PHP数据版本控制与审计追踪数据版本控制记录数据的每一次变更支持回溯到任意历史版本。今天说说PHP中数据版本控制和审计追踪的实现。数据版本控制的核心是保存数据变更的历史记录。phpclass VersionedEntity{private PDO $pdo;public function __construct(PDO $pdo){$this-pdo $pdo;$this-initSchema();}private function initSchema(): void{$this-pdo-exec(CREATE TABLE IF NOT EXISTS entity_versions (id BIGINT AUTO_INCREMENT PRIMARY KEY,entity_type VARCHAR(100) NOT NULL,entity_id INT NOT NULL,version INT NOT NULL,data JSON NOT NULL,changed_by INT,change_reason VARCHAR(500),created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,UNIQUE KEY uk_entity_version (entity_type, entity_id, version),INDEX idx_entity (entity_type, entity_id)));}public function saveVersion(string $entityType, int $entityId, array $data, int $changedBy 0, string $reason ): void{$nextVersion $this-getNextVersion($entityType, $entityId);$stmt $this-pdo-prepare(INSERT INTO entity_versions (entity_type, entity_id, version, data, changed_by, change_reason)VALUES (?, ?, ?, ?, ?, ?));$stmt-execute([$entityType, $entityId, $nextVersion, json_encode($data), $changedBy, $reason]);}public function getVersion(string $entityType, int $entityId, int $version): ?array{$stmt $this-pdo-prepare(SELECT * FROM entity_versionsWHERE entity_type ? AND entity_id ? AND version ?);$stmt-execute([$entityType, $entityId, $version]);$row $stmt-fetch(PDO::FETCH_ASSOC);return $row ? $row : null;}public function getHistory(string $entityType, int $entityId): array{$stmt $this-pdo-prepare(SELECT version, changed_by, change_reason, created_atFROM entity_versionsWHERE entity_type ? AND entity_id ?ORDER BY version DESC);$stmt-execute([$entityType, $entityId]);return $stmt-fetchAll();}public function rollback(string $entityType, int $entityId, int $version): ?array{$versionData $this-getVersion($entityType, $entityId, $version);if ($versionData null) return null;return json_decode($versionData[data], true);}public function diff(string $entityType, int $entityId, int $version1, int $version2): array{$v1 $this-getVersion($entityType, $entityId, $version1);$v2 $this-getVersion($entityType, $entityId, $version2);if (!$v1 || !$v2) return [];$data1 json_decode($v1[data], true);$data2 json_decode($v2[data], true);$diff [];foreach ($data2 as $key $value) {if (!isset($data1[$key]) || $data1[$key] ! $value) {$diff[$key] [old $data1[$key] ?? null, new $value];}}return $diff;}private function getNextVersion(string $entityType, int $entityId): int{$stmt $this-pdo-prepare(SELECT COALESCE(MAX(version), 0) 1FROM entity_versionsWHERE entity_type ? AND entity_id ?);$stmt-execute([$entityType, $entityId]);return (int)$stmt-fetchColumn();}}class VersionedUserService{private PDO $pdo;private VersionedEntity $versions;public function __construct(PDO $pdo){$this-pdo $pdo;$this-versions new VersionedEntity($pdo);}public function createUser(array $data, int $operatorId 0): int{$stmt $this-pdo-prepare(INSERT INTO users (name, email, role) VALUES (?, ?, ?));$stmt-execute([$data[name], $data[email], $data[role] ?? user]);$id (int)$this-pdo-lastInsertId();$this-versions-saveVersion(user, $id, $data, $operatorId, 创建用户);return $id;}public function updateUser(int $id, array $data, int $operatorId 0): void{$oldStmt $this-pdo-prepare(SELECT * FROM users WHERE id ?);$oldStmt-execute([$id]);$oldData $oldStmt-fetch(PDO::FETCH_ASSOC);$sets [];$params [];foreach ($data as $key $value) {$sets[] {$key} ?;$params[] $value;}$params[] $id;$this-pdo-prepare(UPDATE users SET . implode(, , $sets) . WHERE id ?)-execute($params);$this-versions-saveVersion(user, $id, array_merge($oldData, $data), $operatorId, 更新用户);}public function getUserHistory(int $id): array{return $this-versions-getHistory(user, $id);}}$pdo new PDO(mysql:hostlocalhost;dbnametest, root, );$userService new VersionedUserService($pdo);$userId $userService-createUser([name 张三, email testtest.com], 1);echo 用户已创建 ID: {$userId}\n;$userService-updateUser($userId, [name 张三丰], 1);echo 用户已更新\n;$history $userService-getUserHistory($userId);echo 变更历史:\n;foreach ($history as $h) {echo 版本 {$h[version]}: {$h[change_reason]} ({$h[created_at]})\n;}?数据版本控制是审计和数据恢复的基础。每次数据变更都保存完整快照可以回溯到任意历史版本。变更记录包括修改人、修改时间和修改原因便于审计追踪。这种模式特别适合对数据完整性要求高的业务场景。
PHP数据版本控制与审计追踪
发布时间:2026/6/3 8:37:28
PHP数据版本控制与审计追踪数据版本控制记录数据的每一次变更支持回溯到任意历史版本。今天说说PHP中数据版本控制和审计追踪的实现。数据版本控制的核心是保存数据变更的历史记录。phpclass VersionedEntity{private PDO $pdo;public function __construct(PDO $pdo){$this-pdo $pdo;$this-initSchema();}private function initSchema(): void{$this-pdo-exec(CREATE TABLE IF NOT EXISTS entity_versions (id BIGINT AUTO_INCREMENT PRIMARY KEY,entity_type VARCHAR(100) NOT NULL,entity_id INT NOT NULL,version INT NOT NULL,data JSON NOT NULL,changed_by INT,change_reason VARCHAR(500),created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,UNIQUE KEY uk_entity_version (entity_type, entity_id, version),INDEX idx_entity (entity_type, entity_id)));}public function saveVersion(string $entityType, int $entityId, array $data, int $changedBy 0, string $reason ): void{$nextVersion $this-getNextVersion($entityType, $entityId);$stmt $this-pdo-prepare(INSERT INTO entity_versions (entity_type, entity_id, version, data, changed_by, change_reason)VALUES (?, ?, ?, ?, ?, ?));$stmt-execute([$entityType, $entityId, $nextVersion, json_encode($data), $changedBy, $reason]);}public function getVersion(string $entityType, int $entityId, int $version): ?array{$stmt $this-pdo-prepare(SELECT * FROM entity_versionsWHERE entity_type ? AND entity_id ? AND version ?);$stmt-execute([$entityType, $entityId, $version]);$row $stmt-fetch(PDO::FETCH_ASSOC);return $row ? $row : null;}public function getHistory(string $entityType, int $entityId): array{$stmt $this-pdo-prepare(SELECT version, changed_by, change_reason, created_atFROM entity_versionsWHERE entity_type ? AND entity_id ?ORDER BY version DESC);$stmt-execute([$entityType, $entityId]);return $stmt-fetchAll();}public function rollback(string $entityType, int $entityId, int $version): ?array{$versionData $this-getVersion($entityType, $entityId, $version);if ($versionData null) return null;return json_decode($versionData[data], true);}public function diff(string $entityType, int $entityId, int $version1, int $version2): array{$v1 $this-getVersion($entityType, $entityId, $version1);$v2 $this-getVersion($entityType, $entityId, $version2);if (!$v1 || !$v2) return [];$data1 json_decode($v1[data], true);$data2 json_decode($v2[data], true);$diff [];foreach ($data2 as $key $value) {if (!isset($data1[$key]) || $data1[$key] ! $value) {$diff[$key] [old $data1[$key] ?? null, new $value];}}return $diff;}private function getNextVersion(string $entityType, int $entityId): int{$stmt $this-pdo-prepare(SELECT COALESCE(MAX(version), 0) 1FROM entity_versionsWHERE entity_type ? AND entity_id ?);$stmt-execute([$entityType, $entityId]);return (int)$stmt-fetchColumn();}}class VersionedUserService{private PDO $pdo;private VersionedEntity $versions;public function __construct(PDO $pdo){$this-pdo $pdo;$this-versions new VersionedEntity($pdo);}public function createUser(array $data, int $operatorId 0): int{$stmt $this-pdo-prepare(INSERT INTO users (name, email, role) VALUES (?, ?, ?));$stmt-execute([$data[name], $data[email], $data[role] ?? user]);$id (int)$this-pdo-lastInsertId();$this-versions-saveVersion(user, $id, $data, $operatorId, 创建用户);return $id;}public function updateUser(int $id, array $data, int $operatorId 0): void{$oldStmt $this-pdo-prepare(SELECT * FROM users WHERE id ?);$oldStmt-execute([$id]);$oldData $oldStmt-fetch(PDO::FETCH_ASSOC);$sets [];$params [];foreach ($data as $key $value) {$sets[] {$key} ?;$params[] $value;}$params[] $id;$this-pdo-prepare(UPDATE users SET . implode(, , $sets) . WHERE id ?)-execute($params);$this-versions-saveVersion(user, $id, array_merge($oldData, $data), $operatorId, 更新用户);}public function getUserHistory(int $id): array{return $this-versions-getHistory(user, $id);}}$pdo new PDO(mysql:hostlocalhost;dbnametest, root, );$userService new VersionedUserService($pdo);$userId $userService-createUser([name 张三, email testtest.com], 1);echo 用户已创建 ID: {$userId}\n;$userService-updateUser($userId, [name 张三丰], 1);echo 用户已更新\n;$history $userService-getUserHistory($userId);echo 变更历史:\n;foreach ($history as $h) {echo 版本 {$h[version]}: {$h[change_reason]} ({$h[created_at]})\n;}?数据版本控制是审计和数据恢复的基础。每次数据变更都保存完整快照可以回溯到任意历史版本。变更记录包括修改人、修改时间和修改原因便于审计追踪。这种模式特别适合对数据完整性要求高的业务场景。