php mailer and html includes with php variables
Asked Answered
C

5

13

Hello I am trying to send html emails using php mailer class. The problem is i would like to incllude php variables in my email while using includes as to keep things organized. Heres my php mailer....

 $place = $data['place'];
 $start_time = $data['start_time'];

$mail->IsHTML(true);    // set email format to HTML
$mail->Subject = "You have an event today";
$mail->Body = file_get_contents('../emails/event.html');
$mail->Send(); // send message

my question is, is it possible to have php variables in event.html ? i tried this with no luck (below is event.html)..

<table width='600px' cellpadding='0' cellspacing='0'>
<tr><td bgcolor='#eeeeee'><img src='logo.png' /></td></tr>
<tr><td bgcolor='#ffffff'  bordercolor='#eeeeee'>
<div style='border:1px solid #eeeeee;font-family:Segoe UI,Tahoma,Verdana,Arial,sans-serif;padding:20px 10px;'>
<p style=''>This email is to remind you that you have an upcoming meeting at $place on $start_time.</p>
<p>Thanks</p>
</div>
</td></tr>
</table>
Chadbourne answered 14/7, 2011 at 4:2 Comment(4)
Does it work if you make it "event.php" and then properly delimit echo's for the variables?Christology
@Aaron That would still simply get the contents of the file. include/require is the only way to execute a PHP file.Baguette
Yeah I guess I am thinking of grabbing the page with cURL which should execute the php within the target.Christology
@Aaron True, if you hit it as a remote URL but then it's in it's own request and then it's also public which means you don't have access to the same variables you already set up and you have to deal with any possible injection attacks.Baguette
B
21

Yes, very easily with include and a short helper function:

function get_include_contents($filename, $variablesToMakeLocal) {
    extract($variablesToMakeLocal);
    if (is_file($filename)) {
        ob_start();
        include $filename;
        return ob_get_clean();
    }
    return false;
}

$mail->IsHTML(true);    // set email format to HTML
$mail->Subject = "You have an event today";
$mail->Body = get_include_contents('../emails/event.php', $data); // HTML -> PHP!
$mail->Send(); // send message
  • The get_include_contents function is courtesy of the PHP include documentation, modified slightly to include an array of variables.

  • Important: Since your include is processing within a function, the scope of execution of the PHP template file (/emails/event.php) is in that function's scope (no variables immediately available besides super globals

  • That is why I have added extract($variablesToMakeLocal) — it extracts all array keys from $variablesToMakeLocal as variables in the function's scope, which in turn means they are within scope of the file being included.

    Since you already had place and start_time in the $data array, I simply passed that straight into the function. You may want to be aware that this will extract all keys within $data — you may or may not want that.

  • Note that now your template file is processing as a PHP file, so all the same caveats and syntax rules apply. You should not expose it to be edited by the outside world, and you must use <?php echo $place ?> to output variables, as in any PHP file.

Baguette answered 14/7, 2011 at 4:7 Comment(3)
i walk into this knowing this might be a stupid question, but i'm going to ask anyway: is it correct to presume that the $_SESSION (or $_POST) array does NOT need to be passed to $variablesToMakeLocal?Nidanidaros
@Nidanidaros - Correct, they can be accessed anyway (they are superglobals), though I would probably choose to pass it in so that I could sanitize the data beforehand and so the function could be more portable (i.e. used with data from other sources instead of the template or function always using $_SESSION.Baguette
I'm uncertain how I can get this to work.. I set $varsToMakeLocal = array('$toMail' => $toEmail, '$toName' => $toName); and I try to use your $mail->Body = $this->get_include_contents($htmlfile, $varsToMakeLocal); but the mail is intact and the variables don't get replaced.Capitation
F
12

Couple ways to do it:

Token Template

<p> Some cool text %var1%,, %var2%,etc...</p>

Token Mailer

$mail->Body = strtr(file_get_contents('path/to/template.html'), array('%var1%' => 'Value 1', '%var2%' => 'Value 2'));

Buffer Template

<p> Some cool text $var1,, $var2,etc...</p>

Buffer Mailer

$var1 = 'Value 1';
$var2 = 'Value 2';
ob_start();
include('path/to/template.php');
$content = ob_get_clean();
$mail->Body = $content;
Filefish answered 14/7, 2011 at 4:13 Comment(0)
S
3

You can put variables in the html email and then do a string_replace so the contents appear in the email instead of the variables:

try {
    $mail = new PHPMailer(true);
    $body = file_get_contents('phpmailer/subdir/contents.html');
    $body = str_replace('$fullname', $fullname, $body);
    $body = str_replace('$title', $title, $body);
    $body = str_replace('$email', $email, $body);
    $body = str_replace('$company', $company, $body);
    $body = str_replace('$address', $address, $body);
    // strip backslashes
    $body = preg_replace('/\\\\/','', $body);
    // mail settings below including these:
    $mail->MsgHTML($body);
    $mail->IsHTML(true); // send as HTML
    $mail->CharSet="utf-8"; // use utf-8 character encoding
}

This is the setup that worked for me. It not DRY perhaps, but it works.

Salba answered 9/10, 2013 at 5:4 Comment(1)
This turned out to be the only solution that worked for me. Thank you.Eggplant
P
1

Using prodigitalson's token method, the following worked for me. PHP code was:

$e = "[email protected]";
$sc = "2sbd2152g#!fsf";
$body = file_get_contents("../email/recovery_email.html");
$body  = eregi_replace("%e%" ,$sc, $body);
$body  = eregi_replace("%sc%" ,$sc, $body);
$mail->MsgHTML($body);

The HTML was just:

<p>Click this link: www.mysite.com/recover.php?e=%e%&sc=%sc%<p>

The eregi_replace worked better that strtr in my case - (the latter didn't work at all).

Pneumonic answered 19/4, 2013 at 6:19 Comment(0)
D
0

Maybe a little bit late to the party, but here is the method I always use. (Found this one somewhere on stackoverflow but can't find the link to it. so credits for this solution are not for me!)

First thing to do is replace the variables in html email like so:

<p style=''>This email is to remind you that you have an upcoming meeting at {{ place }} on {{ start_time }}.</p>

Then in PHP you first get the contents of the mailtemplate and assign it to a variable, lets say $mailBody. Then make a new array with the variables you would like to insert in the HTML email template. Once set, you can use a loop to get correct varibales inside the email.

$mailBody = file_get_contents('../emails/event.html');
//make the new array
$mailVariables = array();
//Assign needed variables to the new array
$mailVariables['place'] = $data['place'];
$mailVariables['start_time'] = $data['start_time']; 

foreach($mailVariables as $key => $value) {
    $mailBody = str_replace('{{ '.$key.' }}', $value, $mailBody);
}

$mail->IsHTML(true);    // set email format to HTML
$mail->Subject = "You have an event today";
$mail->Body = $mailBody;
$mail->Send(); // send message

This way you can keep everything clean with just a few lines of extra code. I've used this even to send bulk emails with all diffrent body's and a lot of variables and it runs fairly quick.

Hope it helps.

Dichasium answered 26/11, 2022 at 11:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.