Email function using templates. Includes via ob_start and global vars

余生颓废 提交于 2019-12-01 08:53:37

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

?>
Dmitriy Sushko

One of the ways to do this is to read the file content to the variable and then, using regexps, replace the placeholders. So for example you have new-users-template.phtml. You reading it content with $content = file_get_content('new-users-templae.phtml');. In those template you will have placeholders like %%username%%, %%sitename%%, %%siteurl%%. You need to process this content with str_replace, replacing the placeholders. Move this code to some "prepareEmailTemplate" function and put the result of this function to your "send" function.

One solution is to globalize the variables needed not inside the template but inside the function 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();
    /* ... */
}

Another solution is to pass those extra variables as parameters. This maybe ugly as the number of parameters in the set function may grow a lot depending on how many of them you need in your template. To solve this issue, another way of implementing this solution is by passing those extra variables as a hash and create those variables on-the-fly (using the function eval). Here's an example:

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();
    /* ... */
}

Then when you should call send like this:

$SITE_NAME = "www.somewebsite.com";
Email::send("recipient", array('SITE_NAME' => $SITE_NAME));
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!