如何用PHP项目实现用户召回?

wen java案例 2

本文目录导读:

如何用PHP项目实现用户召回?

  1. 核心流程架构
  2. 第一步:用户分群与数据准备
  3. 第二步:生成召回内容(个性化模板)
  4. 第三步:选择触达渠道并发送
  5. 第四步:效果追踪(核心环节)
  6. 第五步:调度与防骚扰(Cron + 限流)
  7. 进阶优化建议

用PHP实现用户召回,通常指通过主动触达(如邮件、短信、推送)重新激活已流失或沉睡的用户,一个完整的PHP用户召回系统通常包括:用户分群触达渠道内容生成效果追踪

下面是一个从基础到落地的实现方案,包含代码示例和关键逻辑。


核心流程架构

系统调度 (Cron) -> 用户分群分析 -> 生成召回策略 -> 发送触达 (Mail/SMS/App Push) -> 效果追踪 (点击/登录)

第一步:用户分群与数据准备

不是所有用户都需要被召回,需要定义 “沉睡用户” 的标准(连续30天未登录,或注册后7天内无订单),这需要在PHP中进行数据查询和逻辑判断。

// 示例:查询出需要召回的“沉睡用户”
class UserRecallService {
    private $db;
    public function __construct($pdo) {
        $this->db = $pdo;
    }
    /**
     * 获取需要召回的沉睡用户列表
     * @param int $days 定义多少天未登录算沉睡
     * @return array
     */
    public function getSleepingUsers(int $days = 30): array {
        $sql = "SELECT id, email, phone, username, last_login_at 
                FROM users 
                WHERE status = 1 
                  AND last_login_at IS NOT NULL 
                  AND last_login_at < NOW() - INTERVAL :days DAY
                  AND (last_recall_at IS NULL OR last_recall_at < NOW() - INTERVAL 7 DAY) -- 避免过度召回
                ORDER BY last_login_at ASC 
                LIMIT 1000"; // 分批处理,防止内存溢出
        $stmt = $this->db->prepare($sql);
        $stmt->execute(['days' => $days]);
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }
}

优化点

  • 使用 last_recall_at 字段控制召回频率(7天内不重复召回)。
  • 加上 LIMIT 分页,通过Cron循环处理大批量用户。
  • 可以结合用户行为标签(如:下单用户、浏览用户)生成更精准的分群。

第二步:生成召回内容(个性化模板)

必须具备个性化和吸引力,PHP可以通过模板引擎或字符串替换实现。

class RecallContentGenerator {
    /**
     * 根据用户数据和召回策略生成内容
     * @param array $user 用户数据
     * @param string $type 'email' | 'sms'
     * @return array ['title' => string, 'content' => string]
     */
    public function generate(array $user, string $type = 'email'): array {
        $username = $user['username'] ?? '用户';
        $promotion = $this->getRandomCoupon(); // 获取一个优惠券代码(从数据库或Redis获取)
        if ($type === 'email') {
            $title = "{$username},你有一张专属优惠券待领取!";
            $content = "亲爱的{$username},好久不见!我们为您准备了一张价值{$promotion['value']}元的优惠券,有效期至本周日。\n点击链接领取:https://yourdomain.com/reclaim?code={$promotion['code']}&uid={$user['id']}";
        } else { // SMS短信用简洁内容
            $title = ''; // SMS一般无标题
            $content = "【YourApp】{$username},您有专属优惠券{$promotion['value']}元,点击领取:https://yourdomain.com/reclaim?code={$promotion['code']}&uid={$user['id']}";
        }
        return ['title' => $title, 'content' => $content];
    }
    private function getRandomCoupon(): array {
        // 实际项目中从数据库获取一个未被领取的优惠券
        return ['code' => 'WELCOME2023', 'value' => 20];
    }
}

关键点

  • 使用 uidcode 生成唯一追踪链接。
  • 对于短信,由于长度限制,必须包含短链和关键行动号召(CTA)。
  • 对于邮件,可以嵌入HTML模板。

第三步:选择触达渠道并发送

PHP原生支持 mail(),但生产环境建议使用第三方SDK(如阿里云短信、SendGrid、极光推送)。

// 使用抽象接口方便扩展
interface MessengerInterface {
    public function send(string $recipient, string $title, string $content): bool;
}
class EmailMessenger implements MessengerInterface {
    public function send(string $recipient, string $title, string $content): bool {
        // 使用 PHPMailer 或 SendGrid SDK
        // 简化示例:
        $headers = "From: recall@yourdomain.com\r\n";
        return mail($recipient, $title, $content, $headers);
    }
}
class SMSMessenger implements MessengerInterface {
    public function send(string $recipient, string $title, string $content): bool {
        // 调用阿里云短信API、Twilio等
        // 假设已配置好 $smsClient
        // return $smsClient->sendSms($recipient, $content);
        return true; // 模拟成功
    }
}
// 发送器
class RecallSender {
    private array $messengers;
    public function __construct() {
        $this->messengers = [
            'email' => new EmailMessenger(),
            'sms'   => new SMSMessenger(),
        ];
    }
    /**
     * 执行单次发送并记录日志
     */
    public function sendRecall(array $user, string $channel): bool {
        $generator = new RecallContentGenerator();
        $content = $generator->generate($user, $channel);
        $recipient = ($channel === 'email') ? $user['email'] : $user['phone'];
        if (empty($recipient)) {
            return false;
        }
        $success = $this->messengers[$channel]->send($recipient, $content['title'], $content['content']);
        // 更新用户的召回记录
        if ($success) {
            $this->logRecall($user['id'], $channel, $content['title']);
        }
        return $success;
    }
    private function logRecall(int $userId, string $channel, string $message): void {
        // 写入数据库 recall_log 表:user_id, channel, sent_at, message_content
    }
}

第四步:效果追踪(核心环节)

没有追踪的召回是盲目的,我们需要追踪用户点击链接最终登录/转化

1 追踪链接处理

reclaim.php 中处理用户点击:

// reclaim.php (短链或支付页)
$code = $_GET['code'] ?? '';
$uid = (int)($_GET['uid'] ?? 0);
if ($uid > 0 && !empty($code)) {
    // 记录点击事件
    $logSql = "INSERT INTO recall_click_log (user_id, coupon_code, clicked_at) VALUES (:uid, :code, NOW())";
    // ... 执行SQL ...
    // 标记用户为“已点击”
    $updateSql = "UPDATE users SET last_recall_clicked_at = NOW() WHERE id = :uid";
    // ... 执行SQL ...
    // 发放优惠券并重定向到优惠券落地页
    // header("Location: /coupon/redeem?code=" . urlencode($code));
    exit("召回成功!优惠券已发放到您的账户。");
}

2 最终转化追踪

在用户登录或下单时检查 last_recall_clicked_at 字段:

// 在用户登录成功后的逻辑中
if (!empty($user['last_recall_clicked_at']) && empty($user['last_recall_converted_at'])) {
    // 标记用户已转化(召回成功)
    $updateSql = "UPDATE users SET last_recall_converted_at = NOW() WHERE id = :uid";
    // ... 执行SQL ...
}

3 数据报表

-- 查询召回效果
SELECT 
   COUNT(DISTINCT user_id) as total_recalled,      -- 总召回发送人数
   SUM(CASE WHEN last_recall_clicked_at IS NOT NULL THEN 1 ELSE 0 END) as total_clicks, -- 点击人数
   SUM(CASE WHEN last_recall_converted_at IS NOT NULL THEN 1 ELSE 0 END) as total_converted -- 转化人数
FROM users WHERE last_recall_at IS NOT NULL;

第五步:调度与防骚扰(Cron + 限流)

在Linux服务器上设置Cron任务:

# 每天凌晨2点执行批量召回
0 2 * * * /usr/bin/php /path/to/your_project/artisan recall:execute

PHP命令行脚本:

// artisian recall:execute (通过CLI运行)
$recallService = new UserRecallService($pdo);
$sender = new RecallSender();
$sleepingUsers = $recallService->getSleepingUsers(30); // 30天未登录
foreach ($sleepingUsers as $user) {
    // 根据用户类型选择渠道:有邮箱用邮件,无邮箱用短信
    $channel = !empty($user['email']) ? 'email' : 'sms';
    $sender->sendRecall($user, $channel);
    // 每发100个暂停1秒,防止被限流
    if ($i % 100 === 0) {
        sleep(1);
    }
}

进阶优化建议

  1. A/B测试:将用户随机分为A/B组,测试不同的标题、优惠券金额、发送时间。
  2. 多波次策略:第一波发邮件,3天无点击再发短信,7天无转化再发Push,记录每个波次的时间戳。
  3. 避免垃圾邮件:使用SPF、DKIM签名,并检查用户是否退订(unsubscribed 字段)。
  4. 使用消息队列:如果用户量很大(>10万),将发送任务写入Redis队列,由多个Worker消费,防止Cron超时。
  5. 合规性:确认用户是否同意接收营销信息,并在邮件/短信中添加“退订”链接。

PHP实现用户召回的核心思路是:

  • 分人(沉睡定义) -> 给饵(个性化优惠) -> 触达(多渠道) -> 追踪(点击/登录) -> 优化(A/B测试)。

通过简单的数据库字段(last_recall_at, last_recall_clicked_at, last_recall_converted_at)就能构建一个闭环的效果追踪系统,相比使用第三方营销平台,自建PHP系统的优势在于:数据完全可控与业务系统深度整合(如实时发放优惠券)、成本更低

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