使用模板的电子邮件功能。 通过ob_start和全局变量包括:(Email function u

2019-07-04 18:08发布

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

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

我也有一堆写有一些PHP变量刺穿纯HTML电子邮件模板。 如/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不返回的内容,而是仅仅将其直接输出,我有缓冲功能,把它包起来:

<?
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瓦尔不会呈现,所以我不得不全球化的模板中的变量:

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

所以,问题是是否有更优雅的解决方案呢? 主要是我用关心我的解决方法ob_start()global 。 出于某种原因,在我看来,奇。 或者,这是非常普遍的做法?

Answer 1:

你可以找到一个更好的解决方案,您的问题这个答案 。
注意PHP的使用提取功能来实例化模板变量。
换句话说,你应该将模板解析逻辑电子邮件发送功能之外。
例如:

<?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());

?>


Answer 2:

一要做到这一点的方法之一是读取文件内容的变量,然后使用正则表达式,替换占位符。 因此,例如,你有新的用户,template.phtml。 你读它的内容与$content = file_get_content('new-users-templae.phtml'); 。 在这些模板,你将有类似的占位符%%username%%%%sitename%%%%siteurl%% 。 你需要处理这些内容与str_replace ,替换占位符。 移动此代码一些"prepareEmailTemplate"功能,并把这个函数的结果到你的"send"功能。



Answer 3:

一个解决方案是需要全球化不是模板里面,但里面的函数变量send

public static function send($to, $subj, $msg, $options = array()) {
    global $SITE_NAME, $SITE_URL, $name;

    /* ... */
    ob_start();
    include '/inc/email/templates/account_created.php';
    $msg = ob_get_clean();
    /* ... */
}

另一种解决方案是通过这些额外的变量作为参数。 这可能是丑陋的参数的数量set功能可以根据您在您的模板有多少人需要成长了很多。 为了解决这个问题,这一解决方案的另一种方式是通过将这些多余的变量作为一个哈希并创建这些变量在即时(使用功能eval )。 下面是一个例子:

public static function send($to, $extra_vars = array()) {
    foreach ($extra_vars as $key => $value) {
        eval("\$$key = '$value';");
    }

    /* ... */
    ob_start();
    include '/inc/email/templates/account_created.php';
    $msg = ob_get_clean();
    /* ... */
}

然后,当你应该打电话发这样的:

$SITE_NAME = "www.somewebsite.com";
Email::send("recipient", array('SITE_NAME' => $SITE_NAME));


文章来源: Email function using templates. Includes via ob_start and global vars