Replace multiple placeholders with PHP?
Asked Answered
T

3

5

I have a function that sends out site emails (using phpmailer), what I want to do is basically for php to replace all the placheholders in the email.tpl file with content that I feed it. The problem for me is I don't want to be repeating code hence why I created a function (below).

Without a php function I would do the following in a script

// email template file
$email_template = "email.tpl";

// Get contact form template from file
$message = file_get_contents($email_template);

// Replace place holders in email template
$message = str_replace("[{USERNAME}]", $username, $message);
$message = str_replace("[{EMAIL}]", $email, $message);

Now I know how to do the rest but I am stuck on the str_replace(), as shown above I have multiple str_replace() functions to replace the placeholders in the email template. What I would like is to add the str_replace() to my function (below) and get it to find all instances of [\] in the email template I give it and replace it with the placeholders values that I will give it like this: str_replace("[\]", 'replace_with', $email_body)

The problem is I don't know how I would pass multiple placeholders and their replacement values into my function and get the str_replace("[{\}]", 'replace_with', $email_body) to process all the placeholders I give it and replace with there corresponding values.

Because I want to use the function in multiple places and to avoid duplicating code, on some scripts I may pass the function 5 placeholders and there values and another script may need to pass 10 placeholders and there values to the function to use in email template.

I'm not sure if I will need to use an an array on the script(s) that will use the function and a for loop in the function perhaps to get my php function to take in xx placeholders and xx values from a script and to loop through the placeholders and replace them with there values.

Here's my function that I referred to above. I commented the script which may explain much easier.

// WILL NEED TO PASS PERHAPS AN ARRAY OF MY PLACEHOLDERS AND THERE VALUES FROM x SCRIPT
// INTO THE FUNCTION ?
function phpmailer($to_email, $email_subject, $email_body, $email_tpl) {

// include php mailer class
require_once("class.phpmailer.php");

// send to email (receipent)
global $to_email;
// add the body for mail
global $email_subject;
// email message body
global $email_body;
// email template
global $email_tpl;

// get email template
$message = file_get_contents($email_tpl);

// replace email template placeholders with content from x script
// FIND ALL INSTANCES OF [{}] IN EMAIL TEMPLATE THAT I FEED THE FUNCTION 
// WITH AND REPLACE IT WITH THERE CORRESPOING VALUES.
// NOT SURE IF I NEED A FOR LOOP HERE PERHAPS TO LOOP THROUGH ALL 
// PLACEHOLDERS I FEED THE FUNCTION WITH AND REPLACE WITH THERE CORRESPONDING VALUES
$email_body       = str_replace("[{\}]", 'replace', $email_body);

// create object of PHPMailer
$mail = new PHPMailer();

// inform class to use smtp
$mail->IsSMTP();
// enable smtp authentication
$mail->SMTPAuth   = SMTP_AUTH;
// host of the smtp server
$mail->Host       = SMTP_HOST;
// port of the smtp server
$mail->Port       = SMTP_PORT;
// smtp user name
$mail->Username   = SMTP_USER;
// smtp user password
$mail->Password   = SMTP_PASS;
// mail charset
$mail->CharSet    = MAIL_CHARSET;

// set from email address
$mail->SetFrom(FROM_EMAIL);
// to address
$mail->AddAddress($to_email);
// email subject
$mail->Subject = $email_subject;
// html message body
$mail->MsgHTML($email_body);
// plain text message body (no html)
$mail->AltBody(strip_tags($email_body));

// finally send the mail
if(!$mail->Send()) {
  echo "Mailer Error: " . $mail->ErrorInfo;
  } else {
  echo "Message sent Successfully!";
  }
}
Telly answered 11/4, 2012 at 12:37 Comment(0)
N
18

Simple, see strtr­Docs:

$vars = array(
    "[{USERNAME}]" => $username,
    "[{EMAIL}]" => $email,
);

$message = strtr($message, $vars);

Add as many (or as less) replacement-pairs as you like. But I suggest, you process the template before you call the phpmailer function, so things are kept apart: templating and mail sending:

class MessageTemplateFile
{
    /**
     * @var string
     */
    private $file;
    /**
     * @var string[] varname => string value
     */
    private $vars;

    public function __construct($file, array $vars = array())
    {
        $this->file = (string)$file;
        $this->setVars($vars);
    }

    public function setVars(array $vars)
    {
        $this->vars = $vars;
    }

    public function getTemplateText()
    {
        return file_get_contents($this->file);
    }

    public function __toString()
    {
        return strtr($this->getTemplateText(), $this->getReplacementPairs());
    }

    private function getReplacementPairs()
    {
        $pairs = array();
        foreach ($this->vars as $name => $value)
        {
            $key = sprintf('[{%s}]', strtoupper($name));
            $pairs[$key] = (string)$value;
        }
        return $pairs;
    }
}

Usage can be greatly simplified then, and you can pass the whole template to any function that needs string input.

$vars = compact('username', 'message');
$message = new MessageTemplateFile('email.tpl', $vars);
Nanji answered 11/4, 2012 at 12:40 Comment(2)
thank you so much, the first bit of code explains it all to me, the class you made is much appreciated but i have not learnt oop yet so will give it a miss but the first sample works great with what i need to do so thanks, much appreciated! :)Telly
@PHPLover: Then please see as well a similar email template question and the answers and Efficient way to replace placeholders with variables.Nanji
B
2

The PHP solutions can be:

Please, find the wide answer at Programmers.StackExchange to find out other approaches on PHP email templating.

Bathtub answered 17/5, 2016 at 21:26 Comment(0)
H
0

Why dont you just make the email template a php file aswell? Then you can do something like:

Hello <?=$name?>, my name is <?=$your_name?>, today is <?=$date?>

inside the email to generate your HTML, then send the result as an email.

Seems to me like your going about it the hard way?

Hebner answered 11/4, 2012 at 12:44 Comment(5)
Because it may introduce a code injection vulnerability? BTW short tags are deprecatedAbalone
if you are replacing "X" with the value of $y, then it is the same net result as replacing $x with the value of $y - so there is no new code injection vulnerability?Hebner
you're persupposing that the template is controlled in the same way as the (rest of the) php codeAbalone
@Abalone short tags are not deprecated. They do require short_open_tags to be enabled in the php.ini file. PSR-1 coding standards suggest to only use <?php ?> or <?= ?> (echo short tags).Aphyllous
Actually since PHP5.4 short tags are on by default nowHebner

© 2022 - 2024 — McMap. All rights reserved.