My name is Magnus Lindgren and I work as a freelance IT-consultant. I run my own business, the company name is New Seed.
At the moment I'm searching for interesting assignments or partners for future projects. You can find information about my experience at my LinkedIn profile or contact me directly at by e-mail.
All web programmers have probably had trouble with browsers caching pages it ought not to. So what can we do about it? Well in good old HTTP 1.0 we had a nice header that simply said:
Pragma: no-cache
Easy huh? Yes. Probably to easy. If not browsers then sure some proxy server will dissobey that simple command and require that we explain it to them more thoroughly. This brings on the next HTTP-command:
Expires: -1
Acctually any invalid date format will do, the meaning should be interpreted as "this page have ceased to be" [mental image of John Cleese banging a parrot on the desk]. Only problem is still some missbehaving browsers and proxys interpret this as "well you might have written an erranous date, so we play nice and cache the page for you still". Cue HTTP 1.1 and we have another header:
Cache-control: no-cache
Oh, remember this directive? Easy huh? Heard it before. Yes, it's to easy to be true as well. The problem with this one is that some missbehaving reverse-proxys apparently fails to deliver these pages through the proxy in what seems to be their inability to forward it since they are not allowed to save it. At least in my case it was a reverse proxy that seemed to think very little of pages it wasn't allowed to keep. We had to give it "Cache-control: private" in order for it to acctually pass the page on. The obvious problem with this is that it no longer prehibits the end user agent (as opposed to a in the middle proxy) to cache the page.
Now all available headers have failed in some way, add to this that someone using HTTP 1.0 might try and send a cache-control which will fail due to it not being part of 1.0 or in reverse someone using 1.1 sending Pragma header which might be ignored due to being replaced by cache-control in 1.1.
What is a programmer to do? Well, since proxys have made me not rely on normal HTTP headers the next step is into HTML and the http-equiv META tags. Let's blast the browser with everything we have:
<meta http-equiv="Expires" content="-1"> <meta http-equiv="Pragma" content="no-cache"> <meta http-equiv="Cache-Control" content="no-cache">
Now no proxy should ever interfere with our headers. The problem with cache-control and pragma remains so if you use HTTP 1.0 the former is ignored and in 1.1 the latter. If we include both we are safe, at least until they decide to probably change the whole thing in a future 1.2 version. We also send the expires tag which should make its way all the way to the browser without being cached. Hopefully at least one of these will be treated with respect by the browser, this is even partly recommended in an old KB-article from Microsoft. Still http-equiv is not as safe as real HTTP headers, it requires the browsers to support them. Some support them better than others (the article is old but still sends my head spinning in dissbelief).
Being dissillusioned by the current state of cache control (not the header, the subject) I ended up doing what probably most people are doing allready. Appending a random 10 character string to every call I ever make effectivly fooling the browser that this information might be improtant and making it update the page properly. Just append it to the back of every GET and include a random field in every POST.
http://www.fireflake.com/?cache=ds4R3HYh4
http://www.fireflake.com/?cache=BawqEw42cf
Not the same page. Obviously. Please don't tell any browser developer this or they might include a "random cache of everything in the known universe"-feature in their next build.
I've recently started developing plugins for Wordpress in PHP. Being an old school Perl programmer PHP comes very easy and MySQL is still same old MySQL. PHP don't have many advantages over Perl in general except one very good one: simplicity. I have always tried to write simple code, not simple in the sense that it doesn't accomplish complex tasks rather in the sense that while being a huge and complex system it is still built with easy to understand blocks of code. With that being said, there are a few shortcuts I rather not take.
The reason I write this is that in all the PHP applications and PHP documentation I've come across regarding serialize() nobody ever mentions database normalization.
PHP Serialize
I found the serialize() function in PHP quite useful, it takes a datastructure and creates a string representation of that structure. This string can later be use with unserialize() to return it to the old structure. An example:
$fruits = array (
"fruits" => array("a" => "orange", "b" => "banana"),
"numbers" => array(1, 2, 3),
);
echo print_r($fruits);
The above code creates an array and prints the result. The output of the above will be:
Array
(
[fruits] => Array
(
[a] => orange
[b] => banana
)
[numbers] => Array
(
[0] => 1
[1] => 2
[2] => 3
)
)
Now if you use serialize on this object the following would happen:
Output:$fruits = serialize($fruits);echo print_r($fruits);
1a:2:{s:6:"fruits";a:2:{s:1:"a";s:6:"orange";s:1:"b";s:6:"banana";}s:7:"numbers";a:3:{i:0;i:1;i:1;i:2;i:2;i:3;}}1Array
A long line of strange numbers, just what the programmer wanted! This data is perfect for transfering or saving the state of a data structure for later use. Calling unserialize() on the above string would return it to the same array that we first had.
Database Design
Most applications use a relational database for storing information. A relational database stores all data in tables of rows and columns (or relations of tuples and attributes if you use the original non-SQL names). To make a database work efficiently the design of those tables, rows and columns are pivotal. Any student of database design have probably been forced to read all of the different levels of database normalization. The normalization process, invented by Edgar F. Codd, involves searching for inefficient database design and correcting it.
The very first rule of database normalization called the first normal form (1NF) stipulates that "the table is a faithful representation of a relation and that it is free of repeating groups." [wikipedia]. This means that there should be no duplicate rows and no column should contain multiple values.
Serialization meets 1NF
What happens if you insert the above serialized data into a column of a row in a database? Well put shortly you get a stored datastructure that can be easily accessed by your application by calling it with the keys for that particular row. The table would probably look something like this:
| key | value |
|---|---|
| 1 | 1a:2:{s:6:"fruits";a:2:{s:1:"a";s:6:"orange";s:1:"b";s:6:"banana";}s:7:"numbers";a:3:{i:0;i:1;i:1;i:2;i:2;i:3;}}1Array |
| 2 | 1a:2:{s:6:"fruits";a:2:{s:1:"a";s:6:"apples";s:1:"b";s:6:"banana";}s:7:"numbers";a:3:{i:0;i:1;i:1;i:2;i:2;i:3;}}1Array |
The use of serialization to encode values into the database might be very tempting. It makes saving complex structures easy without having to worry about database design. Saving data in serialized form is however very inefficient from a database design standpoint, the data should have been stored in separate tables reflecting their internal structure.
As I said in the beginning simplicity is the highest virtue of programming for me, serialize is a simple neat solution for a small problem. What should be remembered though is that serialize is not a swizz army knife that should be used for all the database storage. If you ever think that you will need to search through or handle the information stored, do youself a favour and make it a proper table from the start. In the long run making those tables will be easier than later having to convert all those structures and complex code handling them.

Last friday Guitar Hero Metallica (GH:M) was finally released! I even managed to get it fairly cheap thanks to some trade in of useless old PS3-games that I bought cheap on the second hand market anyway. I had previously only played Guitar Hero on Wii so this was the first time I got one for the PS3 including a guitar. I don't know if the guitar that came with GH:M was better than the usual PS3 or not but it was definetly an improvement over the Wii guitars. It felt alot more solid and especially strumming felt alot better.
I've only played the game a few hours in total since I had other things to do this weekend as well. From the little I've played the game feels alot like an improvement from the previous games. It is technically more difficult but manages to be so in a fun way.
My only problem is that now I have to try and get the old Guitar Hero games for the PS3 so I can retire my old Wii guitars! Either that or I just pick up the coming greatest hits version coming soon.
[ad]

I kind of missed the release of Bionic Commando Rearmed but that might not have been an entierly bad thing, now I can get the game cheaper! The PS3 price just dropped to £3.99 / €4.99 (down from (£6.99 / €9.99) on PSN according to VG247.
Bionic Commando Rearmed is a new version of the old NES classic Bionic Commando. New graphics, new music, on-line features and other improvements. Additionally completing certain checkpoints in this game will unluck features in the upcoming Bionic Commando title.
I think I might try this one out when I get home!
Jag borde försöka få min "Var är Magnus"-blogg att automatiskt dyka upp på denna sida, ska bara orka sätta mig ner och programmera det. Är lite lat när det kommer till privat programmering! Tills vidare får jag göra lite reklam för bloggen och länka den här! Dagens inlägg där är kanske inte så mycket om var jag är just nu som var jag är på väg...
Det är tur att vi har forskare som fokuserar på vad som är viktigt här i världen, nämligen att övertala folk att göra som man vill. Från och med nu ska jag alltid be om tjänster genom höger öra då de tycks vara det bästa sättet att få vad man vill. Enligt forskaren (som hade gjort ett test på 176 personer, tämligen lite kan tyckas) så skulle det hela bero på att det man hör i höger öra behandlas av vänster hjärnhalva vilken är mer logisk och bättre på att hantera språk. Detta skulle i sin tur betyda att man har större sannolikhet att få vad man vill än om vänster hjärnhalva skulle behandla informationen.
En idé vore att skaffa en öronpropp till sin fru och sätta den i vänster öra, skulle det fungera?
Some resources hosted at the domain fireflake.com
© magnus lindgren 2000-2009, magnus@fireflake.com
MMM
:)
Jay Godse
Good point, although the indexing services of Google make searching fairly quick if you host it using GData. However, for most folks, if you need ad-hoc queries, relationsl data in SQL makes more sense.
Check out my site for database design notes using SQLite.
Ricke
Jag håller helt med Peter! Det är omöjligt att få som man vill med kvinnor. Det bästa man kan göra är att göra som man vill i alla fall och be om ursäkt om det blev fel i efterhand. De är så vana vid att vi gör tokfel hela tiden så de märker inte vår utstuderade logik i det här falllet.
Lite grann som att be till Gud.
Dag1: "Snälla gud ge mig en cykel." Funkar inte!
Dag2:"Snälla gud ge mig en cykel." Funkar inte!
Dag3: "Snälla gud ge mig en cykel." Funkar inte!
Dag4: "Snälla gud ge mig en cykel." Funkar inte!
Dag5: "Förlåt mig gud för att jag stal en cykel" FUNKAR!!
Peter K
Jag vet inte om det skulle fungera Magnus. Kvinnors logik är, som vi alla vet, fullkomligt ologisk.
Peter K
Måste göras innan 19:e, bah. Får kolla ikväll om det fortfarande fungerar.
Peter K
Galningar på stan, jo det kan man säga...
http://sydsvenskan.se/skane/article443763/Experter-sagar-scientologitest.html
MMM
Kanske intressant för andra som vill prova... hur man få ett Spotify konto:
http://smexdesign.se/spotify-invites/
Hu
Thanks for posting this; it was very helpful!
I have a tag table where there are literally five thousand plus rows. I was thinking of modifying it so I could just serialise the tags, but searching would be a pain. I've realised the error of my thinking. :P I'll just have to manage with the overpopulous table.
admin
The template on this page seems to convert the " to a non standard character. If you use the serialize command to generate the strings it should work.
admin
Ah, timestamp! Much easier than to generate a random string, why didn't I think of that? :)