使用模板的电子邮件功能

使用模板的电子邮件功能

本文介绍了使用模板的电子邮件功能.通过 ob_start 和全局变量包括的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的 Email() 类.它用于从我的网站发送电子邮件.

I have a simple Email() class. It's used to send out emails from my website.

<?
Email::send($to, $subj, $msg, $options);
?>

我还有一堆用纯 HTML 编写的电子邮件模板,其中包含一些 PHP 变量.例如./inc/email/templates/account_created.php:

I also have a bunch of email templates written in plain HTML pierced with a few PHP variables. E.g. /inc/email/templates/account_created.php:

<p>Dear <?=$name?>,</p>
<p>Thank you for creating an account at <?=$SITE_NAME?>. To login use the link below:</p>
<p><a href="https://<?=$SITE_URL?>/account" target="_blank"><?=$SITE_NAME?>/account</a></p>

为了渲染 PHP 变量,我必须include 模板到我的函数中.但是由于 include 不返回内容而是直接将其发送到输出,所以我不得不用缓冲区函数包装它:

In order to have the PHP vars rendered I had to include the template into my function. But since include does not return the contents but rather just sends it directly to the output, I had to wrap it with the buffer functions:

<?
abstract class Email {
    public static function send($to, $subj, $msg, $options = array()) {
        /* ... */
        ob_start();
        include '/inc/email/templates/account_created.php';
        $msg = ob_get_clean();
        /* ... */
    }
}

之后我意识到 PHP 变量在函数作用域内没有被渲染,所以我不得不将模板内的变量全球化:

After that I realized that the PHP vars are not rendered as they are being inside of the function scope, so I had to globalize the variables inside of the template:

<?
global $SITE_NAME, $SITE_URL, $name;
?>
<p>Dear <?=$name?>,</p>
...

那么问题是是否有更优雅的解决方案?我主要担心我使用 ob_start()global 的变通方法.出于某种原因,这在我看来很奇怪.或者这几乎是常见的做法?

So the question is whether there is a more elegant solution to this? Mainly I am concerned about my workarounds using ob_start() and global. For some reason that seems to me odd. Or this is pretty much the common practice?

推荐答案

您可以在 这个答案.
请注意 PHP extract 函数用于实例化模板变量的用法.
换句话说,您应该将模板解析逻辑移到电子邮件发送功能之外.
例如:

You can find a more elegant solution to your problem in this answer.
Notice the usage of the PHP extract function to instantiate the template variables.
In other words, you should move the template parsing logic outside the e-mail sending function.
For example:

<?php

class SimpleTemplate {
    private $_tpl  = "";
    private $_vars = array();

    function __construct($tpl_name) {
         $this->_tpl = $tpl_name;
    }

    public function __set($name, $value) {
        $this->_vars[$name] = $value;
    }

    public function setVars($values) {
        $this->_vars = $values;
    }

    public function parse() {
        ob_start();
        extract($this->_vars);
        include $this->_tpl;
        return ob_get_clean();
    }
}

abstract class Email {
    public static function send($to, $subj, $msg, $options = array()) {
        /* ... */
    }
}

$tpl = new SimpleTemplate('/inc/email/templates/account_created.php');
$tpl->name = 'Stack Overflow';
$tpl->SITE_NAME = 'site_name';
$tpl->SITE_URL = 'localhost';
Email::send("me@localhost", "Subject", $tpl->parse());

?>

这篇关于使用模板的电子邮件功能.通过 ob_start 和全局变量包括的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-22 13:31