PHP项目EDM模板与变量

wen PHP项目 2

本文目录导读:

PHP项目EDM模板与变量

  1. EDM模板基本结构
  2. PHP模板引擎实现
  3. 更复杂的模板系统
  4. 使用Twig模板引擎(推荐)
  5. EDM模板变量最佳实践
  6. 实际应用示例
  7. 注意事项

我来详细介绍PHP项目中EDM邮件营销模板的定义、变量使用及最佳实践。

EDM模板基本结构

HTML模板示例

<!-- templates/email/welcome.html -->
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">{{subject}}</title>
</head>
<body style="margin:0; padding:0; background-color:#f4f4f4;">
    <table width="100%" cellpadding="0" cellspacing="0">
        <tr>
            <td align="center" style="padding:20px;">
                <table width="600" cellpadding="0" cellspacing="0" style="background-color:#ffffff;">
                    <!-- Header -->
                    <tr>
                        <td style="padding:20px; background-color:#3498db; text-align:center;">
                            <h1 style="color:#ffffff; margin:0;">{{company_name}}</h1>
                        </td>
                    </tr>
                    <!-- Body -->
                    <tr>
                        <td style="padding:30px;">
                            <h2>欢迎您,{{username}}!</h2>
                            <p>感谢您注册我们的服务。</p>
                            <p>您的注册邮箱是:{{email}}</p>
                            <p>注册时间:{{register_time}}</p>
                            <!-- 按钮 -->
                            <table cellpadding="0" cellspacing="0" style="margin:20px 0;">
                                <tr>
                                    <td style="background-color:#3498db; border-radius:25px;">
                                        <a href="{{verify_link}}" style="display:inline-block; padding:12px 30px; color:#ffffff; text-decoration:none; font-size:16px;">
                                            立即验证
                                        </a>
                                    </td>
                                </tr>
                            </table>
                        </td>
                    </tr>
                    <!-- Footer -->
                    <tr>
                        <td style="padding:20px; background-color:#f8f8f8; text-align:center; font-size:12px; color:#888888;">
                            <p>{{copyright}}</p>
                            <p><a href="{{unsubscribe_link}}" style="color:#888888;">取消订阅</a></p>
                        </td>
                    </tr>
                </table>
            </td>
        </tr>
    </table>
</body>
</html>

PHP模板引擎实现

基础模板引擎类

<?php
class EmailTemplate {
    private $templates = [];
    private $cacheDir = 'cache/templates/';
    /**
     * 注册模板
     */
    public function register($name, $path) {
        $this->templates[$name] = $path;
    }
    /**
     * 渲染模板
     */
    public function render($templateName, array $variables = []) {
        // 获取模板内容
        $content = $this->getTemplate($templateName);
        // 替换变量
        return $this->parseVariables($content, $variables);
    }
    /**
     * 获取模板内容
     */
    private function getTemplate($name) {
        if (!isset($this->templates[$name])) {
            throw new Exception("Template '{$name}' not found");
        }
        $path = $this->templates[$name];
        if (!file_exists($path)) {
            throw new Exception("Template file '{$path}' not found");
        }
        return file_get_contents($path);
    }
    /**
     * 解析变量
     */
    private function parseVariables($content, array $variables) {
        // 使用双花括号变量替换
        foreach ($variables as $key => $value) {
            $content = str_replace(
                '{{' . $key . '}}', 
                htmlspecialchars($value, ENT_QUOTES, 'UTF-8'), 
                $content
            );
        }
        return $content;
    }
}

更复杂的模板系统

支持条件和循环的模板系统

<?php
class AdvancedEmailTemplate {
    private $blocks = [];
    private $sections = [];
    /**
     * 模板配置
     */
    private $config = [
        'var_start' => '{{',
        'var_end' => '}}',
        'block_start' => '{%',
        'block_end' => '%}',
        'cache_enabled' => true,
        'auto_escape' => true
    ];
    /**
     * 更强大的模板解析
     */
    public function parse($content, $data) {
        // 1. 处理条件语句
        $content = $this->parseConditionals($content, $data);
        // 2. 处理循环语句
        $content = $this->parseLoops($content, $data);
        // 3. 处理变量
        $content = $this->parseVariables($content, $data);
        // 4. 处理默认值
        $content = $this->parseDefaults($content, $data);
        return $content;
    }
    /**
     * 处理条件语句
     */
    private function parseConditionals($content, $data) {
        return preg_replace_callback(
            '/{%\s*if\s+(\w+)\s*%}(.*?){%\s*endif\s*%}/s',
            function($matches) use ($data) {
                $condition = $matches[1];
                $block = $matches[2];
                // 检查条件变量是否存在且为真
                if (isset($data[$condition]) && $data[$condition]) {
                    return $block;
                }
                return '';
            },
            $content
        );
    }
    /**
     * 处理循环语句
     */
    private function parseLoops($content, $data) {
        return preg_replace_callback(
            '/{%\s*loop\s+(\w+)\s+as\s+(\w+)\s*%}(.*?){%\s*endloop\s*%}/s',
            function($matches) use ($data) {
                $arrayName = $matches[1];
                $itemName = $matches[2];
                $template = $matches[3];
                $result = '';
                if (isset($data[$arrayName]) && is_array($data[$arrayName])) {
                    foreach ($data[$arrayName] as $item) {
                        $temp = $template;
                        foreach ($item as $key => $value) {
                            $temp = str_replace(
                                '{{' . $itemName . '.' . $key . '}}', 
                                $value, 
                                $temp
                            );
                        }
                        $result .= $temp;
                    }
                }
                return $result;
            },
            $content
        );
    }
    /**
     * 处理变量
     */
    private function parseVariables($content, $data) {
        // 处理简单变量
        foreach ($data as $key => $value) {
            if (!is_array($value)) {
                $search = '{{' . $key . '}}';
                $replace = $this->config['auto_escape'] ? 
                    htmlspecialchars($value, ENT_QUOTES, 'UTF-8') : $value;
                $content = str_replace($search, $replace, $content);
            }
        }
        return $content;
    }
}

使用Twig模板引擎(推荐)

安装

composer require twig/twig

配置和使用

<?php
require_once 'vendor/autoload.php';
class EmailService {
    private $twig;
    private $mailer;
    public function __construct() {
        // 配置Twig
        $loader = new \Twig\Loader\FilesystemLoader('templates/email/');
        $this->twig = new \Twig\Environment($loader, [
            'cache' => 'cache/twig/',
            'autoescape' => false  // EDM模板需要保留HTML
        ]);
        // 添加自定义过滤器
        $this->addCustomFilters();
    }
    /**
     * 添加自定义EDM过滤器
     */
    private function addCustomFilters() {
        // 安全去除HTML标签
        $filter = new \Twig\TwigFilter('strip_html', function($string) {
            return strip_tags($string);
        });
        $this->twig->addFilter($filter);
        // 截断文本
        $filter = new \Twig\TwigFilter('truncate', function($string, $length = 100) {
            if (mb_strlen($string) > $length) {
                return mb_substr($string, 0, $length) . '...';
            }
            return $string;
        });
        $this->twig->addFilter($filter);
    }
    /**
     * 发送营销邮件
     */
    public function sendMarketingEmail($to, $template, $data) {
        // 渲染模板
        $html = $this->twig->render($template, [
            'user' => $data['user'],
            'products' => $data['products'],
            'promotion' => $data['promotion'],
            'unsubscribe_url' => $data['unsubscribe_url'],
            'tracking_pixel' => $data['tracking_pixel'],
            'year' => date('Y'),
            'company' => [
                'name' => 'Your Company',
                'address' => '123 Street, City',
                'phone' => '+1 234 567 890'
            ]
        ]);
        // 发送邮件
        // ... 邮件发送代码
    }
}

EDM模板变量最佳实践

变量分类管理

<?php
class EDMTemplateVariables {
    // 系统变量(自动填充)
    public static $systemVariables = [
        'unsubscribe_url' => '',
        'tracking_pixel' => '',
        'current_year' => '',
        'campaign_id' => '',
        'send_time' => ''
    ];
    // 用户变量
    public static $userVariables = [
        'username' => '',
        'email' => '',
        'first_name' => '',
        'last_name' => '',
        'avatar_url' => '',
        'member_since' => '',
        'loyalty_points' => 0
    ];
    // 产品变量
    public static $productVariables = [
        'product_name' => '',
        'product_image' => '',
        'product_price' => '',
        'product_url' => '',
        'discount_percentage' => 0,
        'original_price' => ''
    ];
    // 内容变量
    public static $contentVariables = [
        'subject' => '',
        'preheader' => '',
        'hero_title' => '',
        'hero_description' => '',
        'cta_text' => '',
        'cta_url' => ''
    ];
}

变量验证和清洗

<?php
class VariableValidator {
    /**
     * 验证并清洗变量
     */
    public static function sanitize($variables, $rules = []) {
        $cleaned = [];
        foreach ($variables as $key => $value) {
            // 检查是否需要特殊处理
            if (isset($rules[$key])) {
                $cleaned[$key] = self::applyRule($value, $rules[$key]);
            } else {
                // 默认HTML转义
                $cleaned[$key] = htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
            }
        }
        return $cleaned;
    }
    /**
     * 应用规则
     */
    private static function applyRule($value, $rule) {
        switch ($rule) {
            case 'url':
                return filter_var($value, FILTER_VALIDATE_URL) ? $value : '';
            case 'email':
                return filter_var($value, FILTER_VALIDATE_EMAIL) ? $value : '';
            case 'int':
                return (int) $value;
            case 'float':
                return number_format((float) $value, 2);
            case 'html':
                // 允许部分HTML标签
                $allowedTags = '<a><b><strong><i><em><u><br><p><span><div><table><tr><td><img>';
                return strip_tags($value, $allowedTags);
            default:
                return htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
        }
    }
}

实际应用示例

模板组合使用

<?php
class EDMController {
    /**
     * 发送营销邮件
     */
    public function sendPromotion() {
        // 1. 准备数据
        $data = [
            // 用户信息
            'username' => 'John Doe',
            'email' => 'john@example.com',
            // 促销活动
            'promotion' => [
                'title' => '夏日大促',
                'discount' => '50%',
                'code' => 'SUMMER50',
                'valid_until' => '2024-08-31'
            ],
            // 推荐产品
            'products' => [
                [
                    'name' => '产品1',
                    'image' => 'https://example.com/product1.jpg',
                    'price' => '$99.99',
                    'url' => 'https://example.com/product1'
                ],
                [
                    'name' => '产品2',
                    'image' => 'https://example.com/product2.jpg',
                    'price' => '$149.99',
                    'url' => 'https://example.com/product2'
                ]
            ],
            // 系统变量
            'unsubscribe_url' => 'https://example.com/unsubscribe?token=xxx',
            'tracking_pixel' => 'https://example.com/track?campaign=123',
            'current_year' => date('Y')
        ];
        // 2. 变量验证
        $validator = new VariableValidator();
        $cleanData = $validator->sanitize($data, [
            'email' => 'email',
            'username' => 'text'
        ]);
        // 3. 渲染模板
        $template = new EmailTemplate();
        $html = $template->render('promotion', $cleanData);
        // 4. 发送邮件
        $this->sendEmail($cleanData['email'], $cleanData['username'], $html);
    }
}

注意事项

  1. 安全性:始终对用户输入进行转义
  2. 响应式:确保模板适配移动设备
  3. 测试:在不同邮件客户端测试
  4. 性能:缓存编译后的模板
  5. 追踪:添加打开率和点击率追踪

这样的EDM模板系统既灵活又安全,可以根据业务需求定制不同的邮件模板。

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