Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Email function using templates. Includes via ob_start and global vars

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

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

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>

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

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>
...

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?

like image 888
Geo Avatar asked Oct 27 '25 11:10

Geo


1 Answers

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

?>