tags:

views:

77

answers:

5

Ive written a script to send html emails and all works well. I have the email stored in a separate HTML file which is then read in usin a while loop and fgets(). However, i want to be able to pass variables into the html. For example, in a html file i may have something like..

<body>
    Dear Name <br/>
    Thank you for your recent purhcase
</body>

and i read this into a string like so

$file = fopen($filename, "r");
while(!feof($file)) {
    $html.= fgets($file, 4096);
}
fclose ($file);

I want to be able to replace "Name" in the html file by a variable and im not entirely sure on the best way to do this. I could always make my own tag and then use regex to replace that with the name once ive read the file into the string, but im wondering if there is a better/easier method to do this.

(On a side note, if anyone knows whether its better to use file_get_contents instead of multiple calls to fgets, id be interested to know)

+1  A: 

If you have a lot of variables, you might want to look at an existing templating engine such as Smarty to do the job for you. Alternatively, PHP's str_replace() accepts array parameters and is quite powerful in that regard -- or if you need to make sure that whatever you've replaced cannot in turn be mistaken as a placeholder, strtr() offers that functionality (but is considerably more lethargic).

pinkgothic
thanks for the info, im going to go with the str replace :)
cast01
+3  A: 

You could use str_replace() to define placeholders like

Dear %name
Thank you for your recent purchase of %product

and then replace them on the fly:

$html = str_replace("%name", $order_name, $html);
$product = str_replace("%product", $order_product, $html);

Using file_get_contents() or fopen() is both all right.

Pekka
thats it! Similar to what i was htinking but str_replace is much nicer than regex in this situation.
cast01
+2  A: 

Use a PHP file instead and include it. No need to read it through fgets or replace anything.

ob_start();
include("yourTemplate.html.php");

$html = ob_get_clean();

// $html now has whatever your template output
Matt
worked a treat! i accepted El Yobo's version as it had a more detailed example, but thanks!
cast01
A: 

You may want to consider using a templating system, if you expect any more features in the future.

Stephen
+2  A: 

str_replace() also has the disadvantages of potentially matching and replacing things that you might not want to. Smarty is definitely overkill for this, I would follow Matt's suggestion above by doing something like the following

function getEmailContents(array $vars) {
  extract($vars);

  ob_start();
  include 'email.html.php';
  return ob_end_clean();
}

email.html.php would look like this

<body>
    Dear <?php echo $name; ?> <br/>
    Thank you for your recent purhcase of <?php echo $product; ?>
</body>

and you can call it like this

$emailContents = getEmailContents(array('name' => 'El Yobo', 'product' => 'Something'));

You'll never match anything by mistake this way and it's easily extended with other variables etc. without having to use addition str_replace() calls.

If you need to go much further than that, it might be worthwhile looking at Smarty.

El Yobo
actually this does look like quite a nice way of doing it. Especially in a situation where a customer buys many products, becasue then i can just loop through the array in the html, rather than looping through it, creating the string, and then replacing it in the html file. I dont fully understand what ob__start and ob_end_clean do, its somethin to with the output buffer right?
cast01
okay, i got that working and its much less code! I had to alter a few things first though, the 'return ob_end_clean' just seemed to be returning 1, so after the include i added '$html = ob_get_contents' then i did 'ob_end_clean()' and then i returned '$html', and it works, does this sound reasonable? Are there any drawbacks with doing it this way? Is it safe/efficient? Many thanks!
cast01
Yes, using ob_get_content() and ob_end_clean() is fine. The docs for ob_get_clean() indicate that that's exactly what it does internally anyway (http://au.php.net/ob_get_clean).
El Yobo