我将为您提供一个完整的PHP邮件跟踪系统实现方案。

邮件跟踪系统实现
数据库表结构
-- 邮件跟踪表
CREATE TABLE email_tracking (
id INT AUTO_INCREMENT PRIMARY KEY,
email_id VARCHAR(64) NOT NULL UNIQUE,
recipient_email VARCHAR(255) NOT NULL,
subject VARCHAR(255),
sent_at DATETIME NOT NULL,
opened_at DATETIME,
opened_count INT DEFAULT 0,
user_agent TEXT,
ip_address VARCHAR(45),
status ENUM('sent', 'opened', 'clicked') DEFAULT 'sent',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_email_id (email_id),
INDEX idx_recipient (recipient_email)
);
-- 点击跟踪表
CREATE TABLE email_links (
id INT AUTO_INCREMENT PRIMARY KEY,
tracking_id INT NOT NULL,
original_url TEXT NOT NULL,
redirect_url VARCHAR(255) NOT NULL,
click_count INT DEFAULT 0,
last_clicked_at DATETIME,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (tracking_id) REFERENCES email_tracking(id)
);
-- 点击日志表
CREATE TABLE email_clicks (
id INT AUTO_INCREMENT PRIMARY KEY,
tracking_id INT NOT NULL,
link_id INT NOT NULL,
clicked_at DATETIME NOT NULL,
user_agent TEXT,
ip_address VARCHAR(45),
referrer TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (tracking_id) REFERENCES email_tracking(id),
FOREIGN KEY (link_id) REFERENCES email_links(id)
);
邮件发送类
<?php
class EmailTracker {
private $pdo;
public function __construct($pdo) {
$this->pdo = $pdo;
}
/**
* 生成邮件跟踪ID
*/
private function generateTrackingId() {
return md5(uniqid(mt_rand(), true));
}
/**
* 发送邮件并记录跟踪
*/
public function sendWithTracking($recipient, $subject, $htmlContent) {
// 生成跟踪ID
$trackingId = $this->generateTrackingId();
// 保存发送记录
$stmt = $this->pdo->prepare(
"INSERT INTO email_tracking (email_id, recipient_email, subject, sent_at)
VALUES (?, ?, ?, NOW())"
);
$stmt->execute([$trackingId, $recipient, $subject]);
$trackingRecordId = $this->pdo->lastInsertId();
// 创建跟踪像素 (1x1透明图片)
$trackingPixelUrl = "https://yourdomain.com/track.php?id={$trackingId}";
$trackingHtml = "<img src='{$trackingPixelUrl}' width='1' height='1' alt='' style='display:none'>";
// 处理链接跟踪
$processedHtml = $this->processLinks($htmlContent, $trackingRecordId);
// 组合最终内容
$finalContent = $processedHtml . $trackingHtml;
// 发送邮件(使用PHP mail或第三方库)
$this->sendMail($recipient, $subject, $finalContent);
return $trackingId;
}
/**
* 处理邮件中的链接,添加跟踪
*/
private function processLinks($htmlContent, $trackingRecordId) {
$pattern = '/href=["\'](.*?)["\']/i';
return preg_replace_callback($pattern, function($matches) use ($trackingRecordId) {
$url = $matches[1];
// 跳过不需要跟踪的链接
if (strpos($url, 'http') !== 0) {
return $matches[0];
}
// 创建链接跟踪记录
$stmt = $this->pdo->prepare(
"INSERT INTO email_links (tracking_id, original_url, redirect_url)
VALUES (?, ?, ?)"
);
$redirectUrl = "https://yourdomain.com/click.php?id={$trackingRecordId}&url=" . urlencode($url);
$stmt->execute([$trackingRecordId, $url, $redirectUrl]);
return 'href="' . $redirectUrl . '"';
}, $htmlContent);
}
/**
* 发送邮件
*/
private function sendMail($to, $subject, $htmlContent) {
$headers = "MIME-Version: 1.0\r\n";
$headers .= "Content-type: text/html; charset=UTF-8\r\n";
$headers .= "From: Your Company <noreply@yourdomain.com>\r\n";
mail($to, $subject, $htmlContent, $headers);
}
}
跟踪像素处理文件 (track.php)
<?php
// track.php - 处理打开跟踪
require_once 'config.php';
// 获取跟踪ID
$trackingId = isset($_GET['id']) ? $_GET['id'] : '';
$recipient = isset($_GET['r']) ? base64_decode($_GET['r']) : '';
if (empty($trackingId)) {
// 输出1x1透明像素
header('Content-Type: image/gif');
echo base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7');
exit;
}
try {
$pdo = new PDO('mysql:host=localhost;dbname=yourdb', 'user', 'pass');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// 更新打开记录
$stmt = $pdo->prepare("
UPDATE email_tracking
SET opened_at = IFNULL(opened_at, NOW()),
opened_count = opened_count + 1,
user_agent = ?,
ip_address = ?,
status = 'opened'
WHERE email_id = ?
");
$userAgent = $_SERVER['HTTP_USER_AGENT'] ?? '';
$ipAddress = $_SERVER['REMOTE_ADDR'] ?? '';
$stmt->execute([$userAgent, $ipAddress, $trackingId]);
// 输出1x1透明像素
header('Content-Type: image/gif');
header('Content-Length: 42');
echo base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7');
} catch (Exception $e) {
// 错误日志
error_log("Tracking error: " . $e->getMessage());
// 仍然输出透明像素
header('Content-Type: image/gif');
echo base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7');
}
链接点击处理 (click.php)
<?php
// click.php - 处理链接点击
require_once 'config.php';
$linkId = isset($_GET['id']) ? intval($_GET['id']) : 0;
$trackingId = isset($_GET['tid']) ? intval($_GET['tid']) : 0;
if ($linkId <= 0) {
header('Location: /');
exit;
}
try {
$pdo = new PDO('mysql:host=localhost;dbname=yourdb', 'user', 'pass');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// 获取原始链接
$stmt = $pdo->prepare("SELECT * FROM email_links WHERE id = ?");
$stmt->execute([$linkId]);
$link = $stmt->fetch(PDO::FETCH_ASSOC);
if ($link) {
// 记录点击
$clickStmt = $pdo->prepare("
INSERT INTO email_clicks (tracking_id, link_id, clicked_at, user_agent, ip_address, referrer)
VALUES (?, ?, NOW(), ?, ?, ?)
");
$userAgent = $_SERVER['HTTP_USER_AGENT'] ?? '';
$ipAddress = $_SERVER['REMOTE_ADDR'] ?? '';
$referrer = $_SERVER['HTTP_REFERER'] ?? '';
$clickStmt->execute([$trackingId, $linkId, $userAgent, $ipAddress, $referrer]);
// 更新点击统计
$updateStmt = $pdo->prepare("
UPDATE email_links
SET click_count = click_count + 1,
last_clicked_at = NOW()
WHERE id = ?
");
$updateStmt->execute([$linkId]);
// 重定向到原始URL
header('Location: ' . $link['original_url']);
exit;
}
} catch (Exception $e) {
error_log("Click tracking error: " . $e->getMessage());
}
header('Location: /');
exit;
查询报告功能
<?php
class EmailTrackingReport {
private $pdo;
public function __construct($pdo) {
$this->pdo = $pdo;
}
/**
* 获取邮件打开统计
*/
public function getOpenStats($emailId) {
$stmt = $this->pdo->prepare("
SELECT * FROM email_tracking
WHERE email_id = ?
");
$stmt->execute([$emailId]);
return $stmt->fetch(PDO::FETCH_ASSOC);
}
/**
* 获取邮件列表统计
*/
public function getEmailListStats() {
$query = "
SELECT
email_id,
recipient_email,
subject,
sent_at,
opened_at,
opened_count,
status
FROM email_tracking
ORDER BY sent_at DESC
LIMIT 50
";
return $this->pdo->query($query)->fetchAll(PDO::FETCH_ASSOC);
}
/**
* 获取链接点击统计
*/
public function getLinkStats($emailId) {
$stmt = $this->pdo->prepare("
SELECT
el.original_url,
el.click_count,
el.last_clicked_at,
COUNT(ec.id) as total_clicks
FROM email_links el
LEFT JOIN email_clicks ec ON el.id = ec.link_id
WHERE el.tracking_id = (
SELECT id FROM email_tracking WHERE email_id = ?
)
GROUP BY el.id
");
$stmt->execute([$emailId]);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
/**
* 生成HTML报告
*/
public function generateReport($emailId) {
$emailStats = $this->getOpenStats($emailId);
$linkStats = $this->getLinkStats($emailId);
$html = "<h2>邮件统计报告</h2>";
$html .= "<p>发送给: " . htmlspecialchars($emailStats['recipient_email']) . "</p>";
$html .= "<p>发送时间: " . $emailStats['sent_at'] . "</p>";
if ($emailStats['opened_at']) {
$html .= "<p>打开时间: " . $emailStats['opened_at'] . "</p>";
$html .= "<p>打开次数: " . $emailStats['opened_count'] . "</p>";
$html .= "<p>IP地址: " . htmlspecialchars($emailStats['ip_address']) . "</p>";
} else {
$html .= "<p>状态: <span style='color:red'>未打开</span></p>";
}
if (!empty($linkStats)) {
$html .= "<h3>链接点击统计:</h3>";
$html .= "<ul>";
foreach ($linkStats as $link) {
$html .= "<li>" . htmlspecialchars($link['original_url']) .
" - 点击次数: " . $link['total_clicks'] . "</li>";
}
$html .= "</ul>";
}
return $html;
}
}
使用示例
<?php
// send_email.php
require_once 'EmailTracker.php';
$pdo = new PDO('mysql:host=localhost;dbname=yourdb', 'user', 'pass');
$tracker = new EmailTracker($pdo);
$htmlContent = "
<h1>产品更新通知</h1>
<p>点击<a href='https://example.com/product'>这里</a>查看新产品</p>
<p>访问我们的<a href='https://example.com/blog'>博客</a></p>
";
// 发送邮件并跟踪
$trackingId = $tracker->sendWithTracking(
'recipient@example.com',
'产品更新',
$htmlContent
);
echo "邮件已发送,跟踪ID: " . $trackingId;
// 查看统计
$report = new EmailTrackingReport($pdo);
echo $report->generateReport($trackingId);
注意事项
- 隐私合规:确保符合GDPR等隐私法规
- 邮件服务商限制:某些邮件服务商可能会阻止跟踪像素
- 性能优化:跟踪像素应快速响应
- 安全措施:防止滥用和伪造
这个系统可以准确跟踪邮件的打开和点击情况,为邮件营销提供重要数据支持。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播