PHP 怎么PHP 数据同步

wen PHP项目 2

本文目录导读:

PHP 怎么PHP 数据同步

  1. 场景一:从库 A 同步到库 B(主从复制、ETL)
  2. 场景二:PHP 与第三方 API 数据同步
  3. 场景三:文件数据同步(如CSV、Excel导入)
  4. 场景四:Redis / 缓存与数据库同步
  5. 核心注意事项
  6. 推荐的工具/类库
  7. 总结:你应该选择哪种方式?

PHP 数据同步是一个比较大的话题,因为“同步”的目标不同(数据库、第三方API、文件、Redis缓存等),实现方式也不同。

为了给你最实用的答案,我将其分为最常见的数据同步场景并分别给出代码示例和方案。

从库 A 同步到库 B(主从复制、ETL)

这是最典型的需求,比如把线上库的数据同步到报表库。

方案 1:基于时间戳 / 自增ID 的增量同步(推荐)

适用于源表有 updated_at 或自增 id 的情况。

<?php
//源库连接(MySQL)
$sourceDb = new PDO('mysql:host=source_host;dbname=source_db', 'user', 'pass');
//目标库连接
$targetDb = new PDO('mysql:host=target_host;dbname=target_db', 'user', 'pass');
//假设同步用户表,记录最后同步的ID
$lastSyncId = getLastSyncId(); //从记录表中读取上次同步到的ID
$batchSize = 1000;
$stmt = $sourceDb->prepare("SELECT * FROM users WHERE id > ? ORDER BY id ASC LIMIT ?");
$stmt->execute([$lastSyncId, $batchSize]);
$insertStmt = $targetDb->prepare("REPLACE INTO users (id, name, email, created_at) VALUES (?, ?, ?, ?)");
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
    $insertStmt->execute([
        $row['id'],
        $row['name'],
        $row['email'],
        $row['created_at']
    ]);
    //更新最后同步的ID
    updateLastSyncId($row['id']);
}
echo "同步完成,最后ID: " . $lastSyncId;
?>

方案 2:MySQL Binlog 实时监听(高级)

使用 canal 或 mysql-binlog-connector-java,然后用 PHP 消费,但这通常需要 PHP 作为消费者配合 Kafka/Redis 使用,纯 PHP 实现较少且性能一般。

PHP 与第三方 API 数据同步

订单创建后同步到 ERP 系统(金蝶、SAP),或用户信息同步到推送服务。

推荐:消息队列 + 异步消费

<?php
//生产端:创建订单后发送到队列
function createOrder($orderData) {
    // ... 本地数据库插入操作
    // 同步发送到队列
    $queue = new RedisQueue(); //假设封装好的Redis队列
    $queue->push('sync:erp:order', json_encode($orderData));
    return true;
}
//消费端:独立脚本或Worker(swoole/Workerman)
while (true) {
    $orderData = $queue->pop('sync:erp:order');
    if ($orderData) {
        $order = json_decode($orderData, true);
        try {
            $erpApi = new ErpApi();
            $erpApi->syncOrder($order);
            logSyncSuccess($order['id']);
        } catch (Exception $e) {
            // 记录失败,重试机制
            $queue->retry('sync:erp:order:fail', $orderData);
        }
    }
}

文件数据同步(如CSV、Excel导入)

<?php
//读取CSV并同步到数据库
$file = fopen('data.csv', 'r');
$headers = fgetcsv($file); //跳过标题行
$db = new PDO('mysql:host=localhost;dbname=test', 'root', 'pass');
$stmt = $db->prepare("INSERT INTO products (sku, name, price, stock) VALUES (?, ?, ?, ?) 
                       ON DUPLICATE KEY UPDATE name=VALUES(name), price=VALUES(price)");
while (($row = fgetcsv($file)) !== false) {
    $stmt->execute([
        $row[0], //sku
        $row[1], //name
        $row[2], //price
        $row[3]  //stock
    ]);
}
fclose($file);
echo "文件同步完成";
?>

Redis / 缓存与数据库同步

方案:Cache-Aside 模式

<?php
//读取数据:先查缓存,再查库,回写缓存
function getUser($userId) {
    $cache = new Redis();
    $user = $cache->get("user:$userId");
    if (!$user) {
        // 同步:从数据库加载
        $user = $db->query("SELECT * FROM users WHERE id = $userId")->fetch();
        if ($user) {
            $cache->set("user:$userId", json_encode($user), 3600);
        }
    } else {
        $user = json_decode($user, true);
    }
    return $user;
}
//更新数据:先更新数据库,再删除缓存
function updateUser($userId, $data) {
    $db->update("users", $data, "id = $userId");
    $cache->del("user:$userId"); //删除缓存,下次读取自动同步
}
?>

核心注意事项

  1. 事务与一致性:同步操作需要保证原子性,使用数据库事务。
  2. 失败重试:API同步或队列消费必须有重试机制,否则数据会丢失。
  3. 锁与并发:如果多个进程同时同步同一张表,会导致数据错乱,使用 SELECT ... FOR UPDATE 或 Redis 分布式锁。
  4. 性能考量
    • 小批量(如1000条一批)
    • 不要用 SELECT * 除非所有字段都需要
    • 使用 INSERT ... ON DUPLICATE KEY UPDATE 代替先查后改
  5. 记录同步状态:建立一个 sync_log 表,记录最后一次的同步时间、ID、状态等。

推荐的工具/类库

  • 数据库同步phpMyAdmin 的同步功能(适合页面操作)、MySQL Workbenchpt-table-sync(Percona Toolkit)。
  • ETL 框架Apache Airflow(调度)、Talend(重量级)、Kettle
  • PHP 中间件supervisor(管理常驻进程)、Swoole(异步高性能)、Laravel Horizon(队列监控)。

你应该选择哪种方式?

  • 一次性全量同步:直接用 mysqldump 导入导出,或用 PHP 脚本分页读取写入。
  • 定期增量同步(分钟~小时级):使用方案一(时间戳/ID)。
  • 实时同步(秒级):使用Binlog + Canal + Kafka,PHP 作为消费者。
  • 跨系统API同步:使用消息队列,保证不丢数据。

如果你能告诉我具体要同步什么(数据库到数据库?到API?文件?)和数据量级(几百条?几千万?),我能给出更精准的代码。

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