本文目录导读:

我来详细介绍 PHP 操作审计的几种方式:
基础日志审计
使用文件日志记录
<?php
class AuditLogger {
private $logFile;
public function __construct($logFile = 'audit.log') {
$this->logFile = $logFile;
}
public function log($action, $userId, $details = []) {
$logEntry = [
'timestamp' => date('Y-m-d H:i:s'),
'ip' => $_SERVER['REMOTE_ADDR'] ?? 'unknown',
'user_id' => $userId,
'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? 'unknown',
'action' => $action,
'details' => json_encode($details),
'request_uri' => $_SERVER['REQUEST_URI'] ?? ''
];
$logLine = implode(' | ', $logEntry) . PHP_EOL;
file_put_contents($this->logFile, $logLine, FILE_APPEND | LOCK_EX);
}
}
// 使用示例
$audit = new AuditLogger();
$audit->log('USER_LOGIN', 123, ['username' => 'admin', 'status' => 'success']);
$audit->log('DATA_UPDATE', 123, ['table' => 'users', 'record_id' => 456]);
数据库审计
创建审计表
CREATE TABLE audit_logs (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
user_id INT,
action_type VARCHAR(50),
action_name VARCHAR(100),
target_type VARCHAR(50),
target_id INT,
old_value JSON,
new_value JSON,
ip_address VARCHAR(45),
user_agent TEXT,
request_uri VARCHAR(500)
);
数据库审计类
<?php
class DatabaseAudit {
private $db;
public function __construct(PDO $db) {
$this->db = $db;
}
public function logAction($userId, $actionType, $actionName, $targetType = null,
$targetId = null, $oldValue = null, $newValue = null) {
$stmt = $this->db->prepare("
INSERT INTO audit_logs
(user_id, action_type, action_name, target_type, target_id,
old_value, new_value, ip_address, user_agent, request_uri)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
");
return $stmt->execute([
$userId,
$actionType,
$actionName,
$targetType,
$targetId,
json_encode($oldValue),
json_encode($newValue),
$_SERVER['REMOTE_ADDR'] ?? null,
$_SERVER['HTTP_USER_AGENT'] ?? null,
$_SERVER['REQUEST_URI'] ?? null
]);
}
public function getAuditTrail($criteria = []) {
$sql = "SELECT * FROM audit_logs WHERE 1=1";
$params = [];
if (!empty($criteria['user_id'])) {
$sql .= " AND user_id = ?";
$params[] = $criteria['user_id'];
}
if (!empty($criteria['action_type'])) {
$sql .= " AND action_type = ?";
$params[] = $criteria['action_type'];
}
if (!empty($criteria['date_from'])) {
$sql .= " AND created_at >= ?";
$params[] = $criteria['date_from'];
}
$sql .= " ORDER BY created_at DESC";
$stmt = $this->db->prepare($sql);
$stmt->execute($params);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
}
ORM 模型审计
<?php
trait Auditable {
protected static function bootAuditable() {
static::created(function ($model) {
static::logAudit('create', $model);
});
static::updated(function ($model) {
static::logAudit('update', $model);
});
static::deleted(function ($model) {
static::logAudit('delete', $model);
});
}
protected static function logAudit($action, $model) {
$audit = app(DatabaseAudit::class);
$oldValues = $action === 'update' ? $model->getOriginal() : null;
$newValues = $action === 'delete' ? null : $model->toArray();
$audit->logAction(
auth()->id(),
$action,
get_class($model) . '::' . $action,
get_class($model),
$model->id,
$oldValues,
$newValues
);
}
}
// 使用示例
class User extends Model {
use Auditable;
protected $fillable = ['name', 'email', 'role'];
}
中间件审计
<?php
class AuditMiddleware {
public function handle($request, Closure $next) {
$response = $next($request);
// 记录敏感操作
$sensitiveActions = ['delete', 'update', 'create'];
$currentAction = $request->route()->getActionMethod();
if (in_array($currentAction, $sensitiveActions)) {
Audit::log([
'user_id' => auth()->id(),
'action' => $currentAction,
'route' => $request->path(),
'method' => $request->method(),
'params' => json_encode($request->all()),
'timestamp' => now()
]);
}
return $response;
}
}
实时审计监控
<?php
class RealTimeAudit {
private $auditQueue = [];
public function addAuditEvent($event) {
$this->auditQueue[] = $event;
// 检查是否需要立即处理
if ($this->shouldProcessImmediately($event)) {
$this->processAuditEvent($event);
}
}
private function shouldProcessImmediately($event) {
$criticalEvents = [
'LOGIN_FAILURE',
'PERMISSION_DENIED',
'SENSITIVE_DATA_ACCESS',
'SECURITY_VIOLATION'
];
return in_array($event['type'], $criticalEvents);
}
public function flushAuditQueue() {
foreach ($this->auditQueue as $event) {
$this->processAuditEvent($event);
}
$this->auditQueue = [];
}
private function processAuditEvent($event) {
// 记录到数据库
$this->saveToDatabase($event);
// 如果是关键事件,发送警报
if ($this->isCriticalEvent($event)) {
$this->sendAlert($event);
}
// 记录到日志文件
$this->logToFile($event);
}
private function logToFile($event) {
$logEntry = sprintf(
"[%s] [%s] [User: %s] %s - %s\n",
date('Y-m-d H:i:s'),
strtoupper($event['type']),
$event['user_id'] ?? 'anonymous',
$event['action'],
json_encode($event['details'] ?? [])
);
error_log($logEntry, 3, '/var/log/audit.log');
}
}
完整审计系统示例
<?php
class AuditSystem {
private $storage;
private $config;
public function __construct(array $config = []) {
$this->config = array_merge([
'storage' => 'database', // database, file, both
'log_path' => '/var/log/audit/',
'retention_days' => 90,
'batch_size' => 100,
'async' => false
], $config);
$this->initStorage();
}
public function record($data) {
$auditData = $this->prepareAuditData($data);
if ($this->config['async']) {
return $this->queueAudit($auditData);
}
return $this->storeAudit($auditData);
}
private function prepareAuditData($data) {
return array_merge([
'timestamp' => date('Y-m-d H:i:s'),
'ip_address' => $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0',
'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? '',
'session_id' => session_id(),
'request_id' => uniqid('req_', true)
], $data);
}
public function query($filters = []) {
return $this->storage->query($filters);
}
public function export($format = 'csv', $filters = []) {
$data = $this->query($filters);
return $this->formatExport($data, $format);
}
public function cleanup() {
$expireDate = date('Y-m-d', strtotime("-{$this->config['retention_days']} days"));
return $this->storage->deleteOlderThan($expireDate);
}
public function getStatistics($period = '24h') {
return $this->storage->getStatistics($period);
}
}
最佳实践建议
关键点审计
// 记录关键业务操作
class CriticalOperationAudit {
public function auditUserLogin($userId, $success, $reason = null) {
if (!$success) {
$this->recordFailedLogin($userId, $reason);
// 连续失败锁定
if ($this->getConsecutiveFailures($userId) >= 5) {
$this->lockAccount($userId);
$this->sendSecurityAlert($userId);
}
}
}
public function auditDataExport($userId, $exportType, $exportCount) {
// 大数据量导出需要额外审计
if ($exportCount > 10000) {
$this->recordBulkExport($userId, $exportType, $exportCount);
$this->notifyAdmin("Bulk data export detected");
}
}
}
性能优化
// 批量处理审计日志
class BatchAuditProcessor {
private $buffer = [];
private $bufferSize = 50;
public function add($event) {
$this->buffer[] = $event;
if (count($this->buffer) >= $this->bufferSize) {
$this->flush();
}
}
public function flush() {
if (empty($this->buffer)) {
return;
}
DB::transaction(function () {
foreach ($this->buffer as $event) {
DB::table('audit_logs')->insert($event);
}
});
$this->buffer = [];
}
public function __destruct() {
$this->flush();
}
}
安全检查清单
- ✅ 记录所有敏感操作(登录、权限变更、数据删除)
- ✅ 包含完整上下文(时间、IP、用户、操作细节)
- ✅ 不可篡改的日志存储
- ✅ 定期审计日志清理和归档
- ✅ 敏感信息脱敏处理
- ✅ 审计日志加密传输和存储
- ✅ 支持审计日志查询和分析
- ✅ 异常操作实时告警
这套审计方案可以确保系统的可追溯性和安全性,满足合规要求,根据具体需求选择合适的实现方式。