11.27.2007

Cookies vs. Sessions

Hey there!

At one of my jobs I recently got into using GreyBox. I needed a simple-to-use popup tool to create a popup window when a user clicks on an item in the online store to add it to their cart. They would click "Add," a window would pop up, and they would select how many of the item they wanted. When they clicked 'submit,' the popup window would send that data to a PHP script via AJAX to another page.

This other page would then check some cookies. If the customerID cookie was set, it meant the user was logged in. If the orderID cookie was set, it meant whoever was logged in had a previously created, incomplete order. If the orderID cookie was not set, then a new order was created for the customer logged in, or a temporary customer named "guestXX", where XX is the same number as the new orderID that was generated.

This script worked just fine in IE7. Unfortunately, I don't have a setup readily available to test IE5.5 or IE6. However, in Mozilla some very strange errors would occur. When dumping the array $_COOKIE to debug, I would notice that after the GreyBox window sent the AJAX
request and processed the remote script, a new cookie was created, and for some reason the other cookies would not be output. This new cookie had a strange look, too:

Name: ASPSESSIONIDSASQTBAS
Value: BDINLFLBOLMLADEJFMELJFOM
Expires: Session

Looks suspiciously like an ASP session id to me! I went through and changed all the cookies to sessions, and it solved the problem. The scripts all worked perfectly fine.

I haven't determined whether this was because of GreyBox, which I believe is tied to ASP in some way, or simply a mismatch of AJAX and cookies, or a peculiarity of Firefox. But one thing is for sure: I'm a converted man. No more cookies for this fatty. Sessions for information that needs to be shared across pages during one user's visit, and database storage for the more long-term values.

(I was eating Oreos as I wrote this post.)

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