11.24.2007

Creating HTML emails from dynamic PHP files (or, a primer on output buffering).

Goddag!

This is my first post, and I wanted to share a solution to a problem I faced at work this week.

I was working on a PHP page that displayed an invoice that was to be sent to a customer from the admin section of the website, had the customer requested it.

The structure of the files were like this:

send_confirmation.php: contains a form with two input fields -- the email address of the customer, and the subject of the email. The form used a simple submit button to pass some POST variables back to the same page. Underneath the form, the file invoice.php was included, showing the sender what the customer would see in the email they received.

invoice.php: accesses various tables in the database to pull up the info of the particular order in question for the cutomer and displays the information using tables, inline style attributes, and tags to create an email-friendly-looking HTML invoice.

Here was the dilemma: I wanted to send the email using the contents of invoice.php as the body of the email. However, while invoice.php was included in send_confirmation.php, the contents displayed by PHP's include command weren't stored in a string anywhere, so I wasn't able to just pass invoice.php's contents along with the form submit.

My next thought was to just read the contents of the file into a string and pass that string to the mail function as the body of the email. I tried doing this, using
file_get_contents. This worked; however, the email contained the actual PHP script of that file in its preprocessed form, not as it was to be processed into HTML code. After trying several permutations of this method to see if different functions would process the script and not just give me the contents of the file (saving it as a new file, etc.), I finally came across a set of PHP functions that did just the trick: the output buffer functions.

Essentially, this group of functions let you control how and when the content you want to output within a PHP script is output. For example, anything you pass to the echo statement in PHP is output. Anything from any of the print functions is output. And, content from statements like include and require is output. So, in order to control any of your output, you simply need to employ a few of these functions. Here's how I did it:

First, you have to "turn on output buffering." The code for this is quite simple: ob_start();

Until you do this, output will act normal; that is, your echo statements will be sent to the screen and your include statements will put the contents of the file there as you would expect them to. Once you call this function, however, your output will be stored in the buffer.

Once you have all the output stored that you want to control, you have some options. I haven't fully explored some of these, but taking a look at the functions in that category on php.net will give you an additional idea of what you can do to control the output stored in the buffer. As for me, I just wanted to call include "invoice.php"; and store the results of it into a string variable.

So after calling the include function, I used ob_get_flush, which returns the contents of the output buffer as a string, deletes the contents of the buffer, and closes output buffering. After that I simply needed to strip the whitespace from the resultant string (to avoid a ton of line breaks in the email) using preg_replace('/\s\s+/', ' ', $str); So here is all I needed to do in order to convert my PHP file into static HTML:

ob_start();
include "invoice.php";
$data = ob_get_flush();
$cleandata = preg_replace('/\s\s+/', ' ', $data);


Then just use $cleandata as the body of the email!

Until next time,
Auf wiedersehen!

----------------
Now playing: Evergreen Terrace - Wolfbiker
via FoxyTunes

No comments: