Posted: July 26th, 2008 @ 08:11pm
No Comments »
Ok, so the title is a little misleading, but hopefully only until I explain what I mean. The first session refers to PHP sessions, and the second refers to the concept of sessions. Maybe it needs a little more explanation than that.
Do what?
There aren’t many PHP applications (or indeed web applications) out there that don’t need to maintain some form of user state between page requests. This functionality is commonly known as sessions, and most web development languages provide a built-in mechanism for managing them, and PHP is no exception. It’s probably safe to assume that most people reading this probably know what sessions are and how they work, but I think it’s worth taking a moment to spell it out.
The basic idea of sessions is to retain data between page requests without exposing that data to the client. The common way to do this is to store an ID in a cookie that gets passed between the browser and the server as part of every request. If cookies are unavailable then the ID can be added to all internal URLs as GET or POST variables. On the server site this ID refers to some sort of data storage, whether it be a file, a row in a database or an item in Memcache. To restore the session the application simply reads the data corresponding to the ID it’s been passed, and when the request ends it writes it back with any changes.
Sessions time out in two ways. The cookie will usually live until the user closes their browser. Most implementations will also clean sessions from the server if they are not used for a period of time.
The issues
The default implementation of sessions in PHP (file-based) is perfectly adequate for most applications. However, as an application scales you will almost certainly need to spread the load across multiple servers which creates issues for session management.
One solution is known as sticky sessions. This is where the load balancer keeps track of which session ID’s are on which server and routes subsequent requests accordingly. This creates a shedload more work for the load balancer and depending on usage patterns can lead to an uneven distribution of load.
Another solution is to store the session data in a shared resource such as a database or Memcache. This can create excessive load on that shared resource since sessions will generally be accessed on every page request. If you’re lucky enough to need to scale beyond the point where a single database server can handle that load then you’re looking at solutions such as sharding the sessions across multiple database servers and things start to look decidedly over-complicated. That’s the problem that the architecture this post describes aims to solve.
Read the rest of this entry »
Posted: July 20th, 2008 @ 11:18am
2 Comments »
A share-nothing approach to web development is great for scalability, but there aren’t many web applications that don’t need to share anything between requests. The solution PHP (and most other web development lanugages) utilises is sessions. Sessions basically allow you to store some data between requests. That data is tied to an ID that gets passed between the browser and server in every request, using a cookie, in the URL or in GET/POST parameters.
The default data store for PHP sessions is files, and that’s fine so long as you only have one server, or you can tie each user to one server. When your app scales to the point where each request from a given user could go to one of any number of servers you need to replace this storage mechanism with something accessible from all of them. A database is the obvious choice.
Read the rest of this entry »
Posted: June 21st, 2008 @ 02:59am
No Comments »
I wrote this a while ago for a different domain name but didn’t register it in time. I found the code a few days ago and have just finished putting the finishing touches on it. Nothing special, just a URL shortener with a base length of just 14 characters and a minimum ID length of 1.
http://jmp.li/
For those who care… it’s written in PHP, uses MySQL for storage but the destinations are cached at runtime for efficiency.
Posted: June 18th, 2008 @ 11:09pm
No Comments »
If you’re using PHP you want PHPMailer. If you’re using something else there’s probably an equivalent library (Google is your friend). However, regardless of how you do it you should always consider the impact of your email activities on your users. Unwanted email is one of the biggest problems on the Internet today and the more you can do to present your website as a responsible sender of email the better.
Read the rest of this entry »
Posted: June 17th, 2008 @ 11:26am
Tags: 23x, hdr, jared earle, Photography | 2 Comments »
My mate Jared has posted a most excellent tutorial on High Dynamic Range (HDR) photography. I haven’t tried this yet but I definitely will the next time I’m out with my camera - nice work Jared!

HDR example by Jared Earle, used with permission
Posted: June 8th, 2008 @ 09:42pm
Tags: activerecord, PHP | No Comments »
I wanted an object-oriented way of accessing a database that strikes a good balance between abstracting the details of SQL escaping, insert or update, etc and going too far to the point where the benefits are drowned out by the abstraction. In this article I present the system I am currently using. It does most of what I wanted but certainly has potential for further improvement.
The main reason this post exists is due to a request from someone on the PHP-General list. This code is not intended to be bug-free or extensively tested or indeed anything. Treat it as you would any other experimental code. Read the rest of this entry »
Posted: June 8th, 2008 @ 09:13pm
Tags: javascript | No Comments »
Let me start by saying I hate pop-unders. They clutter up peoples desktops and generally annoy users. Unfortunately they are one of the most effective forms of web-based advertising at the moment, although I’m not sure why. I’ve had a few questions over recent months about how to implement pop-unders so here it is.
Pop-ups are easy, you just call the javascript function window.open with the required parameters. To turn a pop-up into a pop-under is simple. On the page that’s loaded in the pop-up, simply add the following snippet…
<script type="text/javascript">
self.blur();
</script>
That will cause the popped-up window to sink behind whatever opened it.
Note that I accept no responsibility for the complaints you’ll get from users if you start doing this. You’re on your own!
Posted: June 8th, 2008 @ 09:08pm
Tags: PHP | 2 Comments »
Are you seeing backslashes (\) being inserted before quotes in the data you’re using? Have you “solved” the problem using stripslashes? Do you want to know where these are coming from and how to stop it? Of course you do… read on!
Read the rest of this entry »
Posted: June 8th, 2008 @ 08:56pm
Tags: PHP | No Comments »
This is a very common situation. You’re taking input from the user, including their email address. You want to make sure that they’re not feeding you a load of crap, so you want to validate their email address. The best way to do this is with a regular expression, but it’s not a simple task.
Cal Henderson (of Flickr fame) wrote an excellent article a little while ago where he wrote a regular expression against the specification document that defines these things. As Cal points out, that specification is RFC822. Now this potentially has its problems because it was written in 1982 and the rules regarding valid characters in domain names have changed since then, but as far as I can tell his solution has then covered.
Check out his article: http://iamcal.com/publish/articles/php/parsing_email/
Hopefully Cal won’t mind if I reproduce the end result of his work here…
function is_valid_email_address($email)
{
$qtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]';
$dtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]';
$atom = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c'.
'\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+';
$quoted_pair = '\\x5c[\\x00-\\x7f]';
$domain_literal = "\\x5b($dtext|$quoted_pair)*\\x5d";
$quoted_string = "\\x22($qtext|$quoted_pair)*\\x22";
$domain_ref = $atom;
$sub_domain = "($domain_ref|$domain_literal)";
$word = "($atom|$quoted_string)";
$domain = "$sub_domain(\\x2e$sub_domain)*";
$local_part = "$word(\\x2e$word)*";
$addr_spec = "$local_part\\x40$domain";
return preg_match("!^$addr_spec$!", $email) ? 1 : 0;
}
For a recent project I needed a function to just validate a domain name, so I extracted the relevant parts and created the following function…
function is_valid_domain($domainname)
{
$dtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]';
$atom = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c'.
'\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+';
$quoted_pair = '\\x5c[\\x00-\\x7f]';
$domain_literal = "\\x5b($dtext|$quoted_pair)*\\x5d";
$domain_ref = $atom;
$sub_domain = "($domain_ref|$domain_literal)";
$domain = "$sub_domain(\\x2e$sub_domain)*";
return preg_match("/^$domain$/i", $domainname) ? true : false;
}
Posted: June 2nd, 2008 @ 05:10pm
Tags: design | 1 Comment »
I’m loving this one. Content is king!!
Still a few bits that need sorting layout-wise (if the comment form below is the right width then I’ve done it!) but definitely a major improvement on the old new design.
I’ll shortly be migrating the articles into blog posts. I don’t think there’s a legitimate distinction to be made, and blog posts come bundled with comment and trackback abilities which is handy.