PHP项目邮件打开与点击跟踪

wen PHP项目 1

本文目录导读:

PHP项目邮件打开与点击跟踪

  1. 邮件打开跟踪(像素跟踪)
  2. 点击跟踪实现
  3. 数据库表结构
  4. 完整发送邮件示例
  5. 注意事项
  6. 使用PHP库简化实现

我来为您详细介绍如何在PHP项目中实现邮件打开与点击跟踪功能。

邮件打开跟踪(像素跟踪)

基本原理

使用1x1像素的透明图片,当用户加载图片时触发服务器请求。

实现代码

创建跟踪像素PHP文件

<?php
// track_open.php
// 记录邮件打开
function trackEmailOpen($email_id, $recipient_email) {
    // 数据库连接
    $db = new PDO('mysql:host=localhost;dbname=email_tracking', 'username', 'password');
    // 记录打开信息
    $stmt = $db->prepare("INSERT INTO email_opens 
        (email_id, recipient_email, ip_address, user_agent, opened_at) 
        VALUES (?, ?, ?, ?, NOW())");
    $stmt->execute([
        $email_id,
        $recipient_email,
        $_SERVER['REMOTE_ADDR'],
        $_SERVER['HTTP_USER_AGENT']
    ]);
}
// 获取参数
$email_id = $_GET['email_id'] ?? null;
$recipient = $_GET['recipient'] ?? null;
if ($email_id && $recipient) {
    trackEmailOpen($email_id, base64_decode($recipient));
}
// 返回1x1透明GIF图片
header('Content-Type: image/gif');
header('Content-Length: 43');
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');
// 1x1透明像素GIF
echo base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7');
exit;

在邮件中嵌入跟踪像素

<?php
// 发送邮件时添加跟踪像素
function sendTrackedEmail($to, $subject, $htmlBody, $emailId) {
    $trackingPixel = sprintf(
        '<img src="https://yourdomain.com/track_open.php?email_id=%s&recipient=%s" 
             width="1" height="1" style="display:none;" />',
        $emailId,
        base64_encode($to)
    );
    // 在邮件底部添加跟踪像素
    $htmlBody .= $trackingPixel;
    // 发送邮件
    $headers = "MIME-Version: 1.0\r\n";
    $headers .= "Content-type: text/html; charset=UTF-8\r\n";
    mail($to, $subject, $htmlBody, $headers);
}

点击跟踪实现

基本原理

将所有链接替换为跟踪链接,用户点击后先跳转到跟踪服务器,再重定向到目标URL。

创建跟踪链接生成器

<?php
// click_tracker.php
function generateTrackingLink($originalUrl, $emailId, $recipient, $linkId) {
    $params = http_build_query([
        'url' => base64_encode($originalUrl),
        'email_id' => $emailId,
        'recipient' => base64_encode($recipient),
        'link_id' => $linkId
    ]);
    return "https://yourdomain.com/redirect.php?" . $params;
}
// 替换邮件中的链接
function replaceLinksWithTracking($htmlBody, $emailId, $recipient) {
    $linkId = 0;
    return preg_replace_callback(
        '/<a\s+(?:[^>]*?\s+)?href="([^"]*)"/i',
        function($matches) use ($emailId, $recipient, &$linkId) {
            $originalUrl = $matches[1];
            $linkId++;
            $trackingUrl = generateTrackingLink(
                $originalUrl, 
                $emailId, 
                $recipient, 
                $linkId
            );
            return str_replace($matches[1], $trackingUrl, $matches[0]);
        },
        $htmlBody
    );
}

点击重定向处理

<?php
// redirect.php
function trackClick($emailId, $recipient, $linkId, $targetUrl) {
    $db = new PDO('mysql:host=localhost;dbname=email_tracking', 'username', 'password');
    $stmt = $db->prepare("INSERT INTO email_clicks 
        (email_id, recipient_email, link_id, target_url, ip_address, user_agent, clicked_at) 
        VALUES (?, ?, ?, ?, ?, ?, NOW())");
    $stmt->execute([
        $emailId,
        $recipient,
        $linkId,
        $targetUrl,
        $_SERVER['REMOTE_ADDR'],
        $_SERVER['HTTP_USER_AGENT']
    ]);
}
// 获取并验证参数
$targetUrl = base64_decode($_GET['url'] ?? '');
$emailId = $_GET['email_id'] ?? null;
$recipient = base64_decode($_GET['recipient'] ?? '');
$linkId = $_GET['link_id'] ?? null;
if ($targetUrl && $emailId && $recipient && $linkId) {
    trackClick($emailId, $recipient, $linkId, $targetUrl);
    // 重定向到原始URL
    header('Location: ' . $targetUrl, true, 302);
    exit;
}
// 无效参数时重定向到首页
header('Location: https://yourdomain.com');
exit;

数据库表结构

-- 邮件发送记录表
CREATE TABLE email_sends (
    id INT PRIMARY KEY AUTO_INCREMENT,
    campaign_id VARCHAR(50),
    recipient_email VARCHAR(255),
    subject VARCHAR(255),
    sent_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 邮件打开记录表
CREATE TABLE email_opens (
    id INT PRIMARY KEY AUTO_INCREMENT,
    email_id INT,
    recipient_email VARCHAR(255),
    ip_address VARCHAR(45),
    user_agent TEXT,
    opened_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (email_id) REFERENCES email_sends(id)
);
-- 邮件点击记录表
CREATE TABLE email_clicks (
    id INT PRIMARY KEY AUTO_INCREMENT,
    email_id INT,
    recipient_email VARCHAR(255),
    link_id INT,
    target_url TEXT,
    ip_address VARCHAR(45),
    user_agent TEXT,
    clicked_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (email_id) REFERENCES email_sends(id)
);

完整发送邮件示例

<?php
// 发送跟踪邮件完整示例
function sendCampaignEmail($to, $subject, $htmlContent) {
    // 1. 创建邮件发送记录
    $emailId = createEmailSendRecord($to, $subject);
    // 2. 替换链接为跟踪链接
    $trackedContent = replaceLinksWithTracking($htmlContent, $emailId, $to);
    // 3. 添加跟踪像素
    $trackedContent .= sprintf(
        '<img src="https://yourdomain.com/track_open.php?email_id=%s&recipient=%s" 
             width="1" height="1" style="display:none;" />',
        $emailId,
        base64_encode($to)
    );
    // 4. 发送邮件
    $headers = [
        'MIME-Version: 1.0',
        'Content-type: text/html; charset=UTF-8',
        'From: Your Company <noreply@yourdomain.com>',
        'X-Mailer: PHP/' . phpversion()
    ];
    return mail($to, $subject, $trackedContent, implode("\r\n", $headers));
}

注意事项

隐私考虑

  • 遵守GDPR等相关法规
  • 在邮件底部添加退订链接
  • 提供隐私政策说明

技术限制

  • 用户关闭图片加载时无法跟踪打开
  • 某些邮件客户端会缓存图片
  • 需要HTTPS加密传输

性能优化

  • 使用CDN加速跟踪像素加载
  • 异步记录跟踪数据
  • 定期清理过期跟踪记录

使用PHP库简化实现

# 使用Composer安装
composer require maileon/maileon-tracking
composer require snowplow/snowplow-tracker

这个实现方案提供了完整的邮件跟踪功能,包括打开和点击跟踪,根据您的具体需求,可以进行调整和优化。

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