Category Archives: PHP

Introduction to PHP’s Serialize Function

I was tinkering with a WordPress database the other day and was nosing around through some tables, looking for some statistical data which I never found, and noticed that a few of the tables were storing data in an unusual format (to me at least). Specifically one record I found looked like this:

a:6:{s:5:"width";i:250;s:6:"height";i:323;s:14:"hwstring_small";s:22:"height='96' width='74'";s:4:"file";s:32:"/uploads/2008/04/wireframes7.jpg";s:5:"sizes";a:2:{s:9:"thumbnail";a:3:{s:4:"file";s:23:"wireframes7-150x150.jpg";s:5:"width";i:150;s:6:"height";i:150;}s:6:"medium";a:3:{s:4:"file";s:23:"wireframes7-232x300.jpg";s:5:"width";i:232;s:6:"height";i:300;}}s:10:"image_meta";a:10:{s:8:"aperture";i:0;s:6:"credit";s:0:"";s:6:"camera";s:0:"";s:7:"caption";s:0:"";s:17:"created_timestamp";i:0;s:9:"copyright";s:0:"";s:12:"focal_length";i:0;s:3:"iso";i:0;s:13:"shutter_speed";i:0;s:5:"title";s:0:"";}}

Whoa. Looked like some sort of delimited data (it is) but not in a form I recognized. Now over the years I thought I had seen my share of input that is stored in a database. Like most PHP developers I didn’t learn PHP through a class, I learned it by reading and trial and error, but I don’t remember seeing something like this before. Now some of you already know what kind of data this is while others are probably scratching your head and wondering what kind of strange delimited data this is. Isn’t it obvious, that’s an array.

Serialization

cerealAccording to Wikipedia, serialization “is the process of converting an object into a sequence of bits so that it can be persisted on a storage medium (such as a file, or a memory buffer) or transmitted across a network connection link. When the resulting series of bits is reread according to the serialization format, it can be used to create a semantically identical clone of the original object.

Now that I’ve gotten the obligatory definition out of the way, let’s humanize exactly what we’re talking about with a real world example.

Let’s say that you have a feedback form on your website and you want to store all the feedback in a database so that you can analyze it later. Along with the feedback that visitors provide you’re also interested in storing the date and time of their visit, their IP address, and some other information. One way to do this would be to create a table where you had a column for each field in your form. Every record entered in the table would need to insert each field of your feedback form, and other data you wanted to store (e.g. IP address, time submitted), into the table with a long SQL statement. Later if you needed to change your form, say add or remove a field, then you would not only need to change your table schema, but you’d also have to alter your SQL statement. Managing the feedback data this way would also result in the database table growing quite large over time. Since you can’t insert an object or array into a MySQL database (you’ll see an error like Unknown column ‘Array’ in ‘field list’ ) it would be nice if there was another way to easily store all the values we receive, especially if the number of fields could change. So what’s the alternative? PHP’s serialize() function.

PHP’s serialize function was designed for just this sort of job. What it does is basically flatten an array or object into a string (according to php.net, it “Generates a storable representation of a value”). Using our feedback form example, we could pass the $_POST array through the serialize function, and end up with a string which we can store in our database. When the serialize function is done doing its magic with whatever you throw at it, the output is a whole bunch of curly braces and semicolons which looks similar to a:1:{i:0;s:7:"slugdiv";} and the example in the first paragraph. (Note that whenever you enter user submitted data its a good idea to run it through the PHP mysql_real_escape_string function first.) So serializing an array converts it from the array to a string:

serialize

All the array keys and values are preserved by the serialize function so that they can be reconstituted later. If we use serialize() to store our feedback form data, we can eliminate all the fields in our table and just keep the one field for our serialized string. That’s a big space saver. Plus, by storing just the one serialized string in our database we can greatly simplify our SQL statements and no matter how many times we change our form, all the array contents will neatly fit in our table without it or the SQL statements needing to be modified.

Right about now you might be asking, well that’s pretty cool but how do I get my data back out of the database when I need it? No need to fear, just use unserialize() to reverse the process. If you assign the output of unserialize() to a variable then that variable will be a clone of what the original input was. Unserialize will keep all the keys and values of our feedback form’s $_POST array so that they’re instantly available just as they were when they were first created. For example, if you retrieved a serialized row from our table, we could run it through the unserialize function and assign the output to a variable: $reconstituted = unserialize($row[‘feedback’]);.

Sounds great, so what’s the down side? Well by storing our feedback form data in serialized form in the database we lose the ability to use SQL to manipulate the data. So if we wanted to run a query that returned only the email addresses for all of our feedback, then we’d be out of luck. We’d have to use PHP to pull all the data out of the table, unserialize it, and then search through it using PHP instead of MySQL. If our data was stored in unserialized form, where each column corresponded to a field in our feedback form, then searching through and manipulating the data would be far faster and easier with MySQL. So knowing when to use serialization is important. Storing user preferences, or say attributes for an image (like WordPress does), is a perfect use for serialization. If you’ll have the need to search, update or delete parts of serialized data, or otherwise manipulate parts of the data you’re storing, then serialization may not be the way to go. However if you simply need to store arrays or objects in a database so that they can be pulled out in their entirety later, it may be the perfect solution.

PHP Pagination Class

Some of you have asked for more examples of the PHP pagination class I wrote, specifically the same examples I’m using here on the site. The database comes from
MySQL’s free example databases available at http://dev.mysql.com/doc/#sampledb (my example uses the world database). The two examples I use here can be seen at
http://www.catchmyfame.com/paginator/example.php and http://www.catchmyfame.com/paginator/example-form.php. You can download both PHP files, along with the
pagination class in a zip file. Don’t forget to grab the sample database from MySQL.

Note that the MySQL site seems to be undergoing some updates and the sample databases are hard to find. If the above links don’t work try http://dev.mysql.com/doc/index-other.html

You Learn Something New Everyday

I’ve been coding in PHP for probably eight years and thought I knew the language pretty well. Was I surprised the other day when I came across someone else’s code and stared at it blankly, wondering why they had done what they did, and why wasn’t it generating an error. Specifically they had something like this:

echo "Your IP address is {$_SERVER['REMOTE_ADDR']}";

Why were those curly brackets in the echo statement and why wasn’t this giving me errors? I removed the curly brackets and as expected, I received syntax errors. Apparently the {} were magical. Now in my own code, I would typically write the above line like:

echo "Your IP address is " . $_SERVER['REMOTE_ADDR'];

or

echo "Your IP address is $_SERVER[REMOTE_ADDR]";

Now method one is perfectly valid code, but it’s a bit ugly having to starty and stop the string to insert a variable. Method 2 is somewhat wrong as the quotes have been removed from the server array key.  According to php.net, “Always use quotes around a string literal array index. For example, $foo[‘bar’] is correct, while $foo[bar] is not.” But with this new, more compact method, I could make my code cleaner.  I was off to learn more.

After some searching I discovered that PHP will allow you to place curly brackets around a variable in a string (either around the entire variable or with the dollar sign sticking out). “If a dollar sign ($) is encountered, the parser will greedily take as many tokens as possible to form a valid variable name. Enclose the variable name in curly braces to explicitly specify the end of the name. Similarly, an array index or an object property can be parsed. With array indices, the closing square bracket (]) marks the end of the index. The same rules apply to object properties as to simple variables. ” Who knew? I must’ve missed this day during PHP 101 class. Here’s the example from the manual:

<?php
$beer 'Heineken';
echo "$beer's taste is great"// works; "'" is an invalid character for variable names
echo "He drank some $beers";   // won't work; 's' is a valid character for variable names but the variable is "$beer"
echo "He drank some ${beer}s"// works
echo "He drank some {$beer}s"// works
?>

So in a nushell, when using variables in a string you are allowed to enclose the varable in curly brackets to allow variable expansion without having to jump in and out of quotes, or drop quotes. Who doesn’t love PHP?

Bracket Style and Indenting Code

I’ll try to keep this short. Having been coding for years I’ve seen a lot of examples of how other people write code. Now while there are certain requirements in coding, there are areas where you can inject your own person style or preference. One area that has always bugged me is how code is indented and how brackets are used to separate blocks of code. Here’s a very simple example of how I normally code a simple if/else block:

if (hours < 24 && minutes < 60 && seconds < 60)
{
 return true;
}
else
{
 return false;
}

This is known as Allman style (named after Eric Allman, the developer of sendmail). The most common variant of this would be K&R style (from Kernighan and Ritchie’s book The C Programming Language) and the same code looks like this:

if (hours < 24 && minutes < 60 && seconds < 60) {
 return true;
} else {
 return false;
}

Equivalent in every way except readability. Some people call this “The One True Brace Style” because it’s been around so long. The major difference is that the opening bracket is placed at the end of the line that the control statement is on where in Allman style the brackets are each on their own line.

To me it makes sense to make code as readable as possible by lining up brackets to match the block they go with. It becomes apparent what blocks of code belong to what conditions.

Allman style
 
K&R style

If I was to have another condition nested within the example, it would look like this:

if (hours < 24 && minutes < 60 && seconds < 60)
{
 if(hours % 2 == 0)
 {
 	return true;
 }
 else
 {
 	return false;
 }
}

Again, very readable.

The funny thing about K&R style is that its roots seems to be based in the fact that programmers used to have to deal with limited screen space and by squishing the brackets together with the blocks that they belonged to, it saved precious screen real estate. Most programmers either picked up the style they use most often from learning coding in a class or by following the examples set by others, while other programmers code for readability, especially now that space isn’t the issue it once was.

While Allman and K&R are just two of the most popular styles (see
http://en.wikipedia.org/wiki/Indent_style
and
http://en.wikipedia.org/wiki/Programming_style
for some others and a detailed explanation about the history of each)

(please pardon the less than perfect wordpress code formatting)

Simple Pagination Class Revisited

I wanted to make a small addition to the pagination class talked about at http://www.catchmyfame.com/2007/07/28/finally-the-simple-pagination-class/. I added another example which uses a basic form at http://www.catchmyfame.com/paginator/example-form.php. This is very similar to the first example (http://www.catchmyfame.com/paginator/example.php) where the query is hard coded. This new example is meant to show how the pagination class can be used with forms where the data determines the query. In this case, the pull down menu for a continent selection determines the query. Note that the pagination class works fine with both GET and POST requests.