
I use firebug for a while and I love it especially for CSS and JS debugging. Today I stumbled over Yslow and did some tests with it one some of my clients pages and I love the results.
YSlow can help you to analyze all the referenced elements on a webpage. It shows their sizes, how they behave when a page is taken from the browser-cache, shows optimization hints and enables a easy way to optimize the output of your dynamically created webpage :) ... you'll love it.
Get YSlow here :)
6/30/2008
YSlow - powerful FF extension
6/23/2008
Factory [GoF]
Do you remember the Façade pattern post? Sure you do :) - I described a child which asked his granny whether she could bake some cookies. So how this happens in a formal way was describe within the Façade pattern post ;) but the basic action "to ask for sth." is described here...
As you might remember we had a child, probably a lazy one, which was in the mood to eat some cookies but since the cookie tin was empty it asked his granny to bake some new. In OOP thats nearly the same - when you'd to have a (complex) object and if you don't already have one you need someone who creates it or you do it yourself but since you need remember all the steps to create it, that's something for programmers who likes to type :P
So normally you create a method which wraps up all the code to create the complex object. Or maybe you have a Aggregate and you don't want that everyone needs to know how it is build up then this method should be the only way to access the Aggregate.
You see now how you can benefit when you have a Factory available - but there are also some drawbacks. Factories tend to be hard to extend - this happens because the factory has a very deep (mostly hard-coded) knowledge of the objects it creates and normally all the wiring happens statically. If you're looking for a dynamic way to wire up your objects you might end making heavy use of reflection. In normal projects this might be a bit too much ;)
A normal factory method, for a cookie which requires to have 3 flavors, a predefined size and that it's baked before anyone consumes it, could look like this:
class Cookie {
// ...
/*
* Create a Cookie object which consists
* of 3 flavors and has a defined size.
*/
public function getInstance() {
$c = new Cookie();
$c->setFlavor(Cookie::randomFlavor());
$c->setFlavor(Cookie::randomFlavor());
$c->setFlavor(Cookie::randomFlavor());
$c->setSize(Cookie::randomSize());
$c->bakeIt();
return $c;
}
}
If your software contains some complexity where you want to switch the used objects (created by a factory) without modifying the clients, which make use of the factory, you'll end up with the so called Abtract factory.
Let's say you have two types of Cookies - the first one is a high-quality cookie with a bunch of different flavors and the second one is a normal chocolate-cookie. The high-quality cookie is created by your granny (slow but mind-blowing taste), the cookies with the lower quality are the result of mass-production. Your "client" is a wrapping machine which does everything to deliver the cookies to some customers.
So the wrapping machine won't care what kind of cookies are prepared for delivering and so it doesn't matter who the creator is - the only thing it has to know is how it can access the cookies... some kind of interface.
So the entire szenario could look like this:
class Cookie {
}
interface CookieFactory {
abstract function createCookie();
}
class Granny implements CookieFactory {
public function createCookie() {
$cookie = new Cookie();
// do some wierd cookie-creation stuff //
return $cookie;
}
}
class MassProduction implements CookieFactory {
public function createCookie() {
return new Cookie();
}
}
class wrappingMachine {
public function run(CookieFactory $factory) {
$i = 6;
$package=array();
while($i--) {
$package[] = $factory->createCookie();
}
return $package;
}
}
Client-code could look like this;
$wrapper = new wrappingMachine();
$highQualityCookiePackage = $wrapper->run(new Granny());
$lowQualityCookiePackage = $wrapper->run(new MassProduction());
Thats mostly what you can achieve with some normal Factories in the GoF-meaning. Some other interesting ways of object creation are the Plugin pattern and the Prototype pattern. :)
6/20/2008
Query Object [PoEEA]
Maybe you remember the Specification Pattern I explained some weeks ago. It enabled a easy and intuitive searching within large object-collections. A drawback of my example was that I stored the objects in the memory. This can be really ineffective if you want a single object out of hundreds, because you have to create all of them to see which one fits the specification.
Normally you want to limit the number of objects and you also don't store large datasets in memory. The idea of the Query Object pattern is that it enables a usage, comparable to the specification pattern, for objects which are persisted in a database. The benefit is that it creates a query to exclude objects which won't satisfy your needs and therefore you wont mess up the memory anymore.
Once you have a query-object in place you should not get in touch with SQL anymore because it can encapsulate SQL completely, at least if you also have some kind of data mapping (coming soon), which is a great benefit for everyone who is not so familiar with SQL. (But don't forget, regarding performance, SQL-optimization is a very important thing).
So what we need for the Query Object in first place is a object, I'll use the Cookie out of the specification pattern post again. Then we need criteria-objects which hold the information for a single criteria, (determined by "database-field", "operator" and "value") and we also need the Query Objects itself to wrap up the SQL-querying and the object creation somehow.
A very simple example could look like this:
Show PHP Source Code
interface Critera {
public function getWhereClause();
}
class CookieCriteria implements Critera {
private $operator,$field,$value;
protected function __construct($operator,$field,$value) {
$this->operator=$operator;
$this->field=$field;
$this->value=$value;
}
public function getWhereClause() {
return implode(" ",array($this->field,$this->operator,$this->value));
}
public static function matches($field,$value) {
return new CookieCriteria("LIKE",$field,'"'.$value.'"');
}
public static function greaterThan($field,$value) {
return new CookieCriteria(">",$field,$value);
}
}
class CookieFinder {
protected $criterias;
public function addCriteria(Critera $criteria) {
$this->criterias[] = $criteria;
}
public function generateSQL() {
$sql = "SELECT * FROM cookies";
if(sizeof($this->criterias)) {
$where=array();
reset($this->criterias);
while(list(,$criteria)=each($this->criterias)) {
$where[] = $criteria->getWhereClause();
}
$sql.= sizeof($where)?" WHERE ".implode(" AND ",$where):"";
}
return $sql;
}
public function find() {
$collection = array();
if(!$result = mysql_query($this->generateSQL())) {
throw new Exception(mysql_errno());
}
while($row = mysql_fetch_assoc($result)) {
$collection[] = new Cookie($row['name'],$row['flavor'],$name['size']);
}
return $collection;
}
}
Possible client code could look like this:
$finder = new CookieFinder();
$finder->addCriteria(CookieCriteria::matches("name","Granny%"));
$finder->addCriteria(CookieCriteria::greaterThan("size",100));
$cookies = $finder->find();
We just pick up the Query Object, add one or more criteria and ask it to create the objects which fit them.
So this example is not as powerful as the one I used for the Specification pattern, but it should be a easy task to create some kind of "nested criteria objects".
Query objects normally make use of data-mapping so that you can handle various classes, stored in different tables/databases, with a single and generic Query Object. This also enables to avoid SQL-Injection, since you're able to validate the fields and values before you sent them to your database, also some kind of database abstraction would be possible.
With the "Query Object by example", which requires to build up a single object which is used as blueprint for the required objects, exists another flavor of this pattern which is very handy to use and more descriptive.
But no matter which flavor you prefer, Query Objects bring some real benefits when you've to handle complex datasets - for smaller projects the effort might be to much so be careful where you use it.
6/16/2008
Façade [GoF]
If a child is in the mood to eat a fresh cookie it normally asks his granny for one. Like this:
Child: Grannyyyyy?
Granny: Yes my dear?
Child: Could you mix about 2 cups of sugar, 1/2 cup of butter and 1/2 cup of milk in a saucepan and boil it for a minute. And could you, after you removed the saucepan from the heat, mix in some cocoa powder and 3 cups quick cooking oats and form some cookies? Pleeease?
Hm you're right that's not very realistic - it's more like: "Grannyyyy? Could I have a cooookieee pleeeease?" ....the granny knows what to do and the child will get it's cookie
So what happens if you have a pice of software which provides cookies some services for other parts of your software? The most people (especially programmers) are lazy and they won't remember all the details of a complex structure. They remember the place or object which can run a certain task but there's no need to know the deeper structure of that object - the only thing which is important if your using a service of an object is that it doesn't fail.
So the Façade pattern is a structural pattern which more or less describes that you create a object with an simplified interface, so that you can hide complex structures. You can also use a Façade to wrap up some poorly designed APIs into a single well designed API. And the larges benefit of a Façade object is that it makes APIs more readable and therefore enables flexible and easy development.
So maybe you're missing the example-code for this pattern, but since it's not that concrete as others, I've not implemented a special example for it. But I already used a Facade in some way, if you look at the Specification pattern, you'll find the functions getSmallChocolateCookies() and getLargeCookies(). Both show in a tasty way what I described here :)
6/11/2008
Inherit abstract functions....
A error I find from time to time when I work with inheritance is this one:
Fatal error: Can't inherit abstract function Cookie::setFlavor() (previously declared abstract in ChocolateCookie) in ...
This happens when you try to define multiple abstract classes or interfaces with the same abstract functions - it's right that this errors shows up, but today I stuck on this error for a while because I did not see the reason for that - so that's a reminder for me ;)
And the tasty example to reproduce this error:
abstract class Cookie {
abstract public function setFlavor($flavor);
}
abstract class ChocolateCookie extends Cookie {
abstract public function setFlavor($flavor);
}
There are also some rejected bugreports about that :P #35057 #35832 #41145
new TYPO releases
I just saw that the TYPO3 guys released a new version of the popular Enterprise CMS (www.typo3.org). The changelog shows that they mainly changed some security issues and that a lot of smaller changes in the backend happend - one change relates to the problems in the new Firefox 3 where all the frames in the backend are mixed up for some compatibility reason... this was also the reason why the also updates the 4.0.x branch and the 4.1.x branch ...
TYPO3 source package downloads / TYPO3 upgrading guide
6/09/2008
www.cookiepattern.com
To keep my motivation high I just registered www.cookiepattern.com - so for today this was $1 per visitor :P
6/07/2008
Self-extracting PHP archive
The __halt_compiler(); function in php enables to store some additional data in a php-file without blowing up the memory. A very nice possibility is to use this for a self-extracting php file as installation-packages of your php application.
A wile ago I created a script which automatically creates such a archive and I think you might like it....for the impatient ones: Download / Download as Zip.
Before I start to show how the entire script works I'd like to show you a small example so that you can see how the __halt_compiler(); function can be used to store some data at the end of a file:
<?php
$fp = fopen(__FILE__, 'r');
fseek($fp, __COMPILER_HALT_OFFSET__);
$i=0;
while($buffer = fgets($fp)) {
echo ($i++). ":". $buffer."<br/>";
}
;
__HALT_COMPILER();Line 1
Line 2
Line 3
Last line
The first thing you might mention is, that the closing "?>" is missing, but since the function-name is nearly self-explaining you should realize very fast what the output of the script might be ;)
If that's working the question is what's needed for a script which is meant to create and extract a archive? The first thing is a way to create the archive itself. I used the PHP-builtin ZipArchive for that. The second thing is a script which is able to extract this archiv (using the method show above). That's handled by the following snippet:
<?php
try {
$zipfilename = md5(time()).'archive.zip'; //remove with tempname()
$fp_tmp = fopen($zipfilename,'w');
$fp_cur = fopen(__FILE__, 'r');
fseek($fp_cur, __COMPILER_HALT_OFFSET__);
$i=0;
while($buffer = fread($fp_cur,10240)) {
fwrite($fp_tmp,$buffer);
}
fclose($fp_cur);
fclose($fp_tmp);
$zipfile = new ZipArchive();
if($zipfile->open($zipfilename)===true) {
if(!$zipfile->extractTo('.')) throw new Exception('extraction failed...');
} else throw new Exception('reading archive failed');
$zipfile->close();
unlink($zipfilename);
} catch (Exception $e) {
printf("Error:<br/>%s<br>%s>",$e->getMessage(),$e->getTraceAsString());
};
__HALT_COMPILER();[zipdata is appended here later]
As you see that's no rocket-science just read the data, pass it to the ZipArchive object via a temporary file and extract the archive.
If that's working then you need a script which brings the PHP extraction script and the zip-data together. And since we want to have a single script for the creation of our self extracting php archive, it would be very odd if we'd place the "template" for the extraction in a separate file. That's the reason why I just use the same method as above for this script and this time the data is php code instead of zip-data:
<?php
try {
$sourcefolder = 'compressthis/'; // maybe you want to get this via CLI argument ...
$targetname = 'phparchive.php';
$zipfilename = md5(time()).'archive.zip'; // replace with tempname()
// create a archive from the submitted folder
$zipfile = new ZipArchive();
$zipfile->open($zipfilename,ZipArchive::CREATE);
addFiles2Zip($zipfile,$sourcefolder,true);
$zipfile->close();
// compile the selfextracting php-archive
$fp_dest =fopen($targetname,'w');
$fp_cur = fopen(__FILE__, 'r');
fseek($fp_cur, __COMPILER_HALT_OFFSET__);
$i=0;
while($buffer = fgets($fp_cur)) {
fwrite($fp_dest,$buffer);
}
fclose($fp_cur);
$fp_zip = fopen($zipfilename,'r');
while($buffer = fread($fp_zip,10240)) {
fwrite($fp_dest,$buffer);
}
fclose($fp_zip);
fclose($fp_dest);
unlink($zipfilename);
} catch (Exception $e) {
echo $e->getTraceAsString();
}
function addFiles2Zip(ZipArchive $zip,$path,$removeFirstFolder=false) {
$d = opendir($path);
while($file = readdir($d)) {
if ($file == "." || $file == "..") continue;
$curfile=($removeFirstFolder)?substr($path.$file,strpos($path,'/')+1):$path.$file;
if(is_dir($path.$file)) {
$zip->addEmptyDir($curfile);
addFiles2Zip($zip,$path.$file.'/',$removeFirstFolder);
} else {
$zip->addFile($path.$file,$curfile);
}
}
closedir($d);
}
__HALT_COMPILER();[the script shown above]
If you all wrap up into a single script the you'll have something like the script I already mentioned.
I think that it could be useful to have a version with a better error-handling and maybe also some CLI functions so that there's no need to edit the script itself everytime... I'll keep you updated as soon as I have something like that :)
6/04/2008
Plugin [PoEAA]
I'm sure you're pretty often in the situation that you have to switch something depending on the context you're currently in. For example most people change their eating habits before summer - I also do :P
Sometimes this is what you also want to have in your software. To achieve different behaviour you normally just implement two different classes or aggregates and since they have the same "meaning" they normally share a interface (a.k.a Separated Interface). But who decides which implementation fits into the current environment/context?
The easiest way is to have a Factory Method with a small condition to decide this, but this method might grow very fast if you have various options. In this situation its also a matter of form to move this decision into some kind of configuration(-file) so that there's only on file which differs in various environments.
Martin Fowler suggests to place some kind of mapping into the configuration-file, so that your Factory knows which implementation to instantiate in the current context. The key for the mapping in this case is the name of the Separated Interface.
As you see in the example code below, there are Cookie Tins which create contain Cookies and depending on the current month you want to use a more or less restrictive Cookie Tin. In May, June and July you restrict your application to create max. 5 cookies, the rest of the year you don't care :P
Show PHP Source - Main Classes
// The Separated Interface
interface CookieTin {
public function getCookieInstance();
}
class NormalTin implements CookieTin {
public function getCookieInstance() {
return new Cookie();
}
}
class DietTin implements CookieTin {
protected $i=0;
public function getCookieInstance() {
return ($this->i++ < 5)?new Cookie():new NullCookie();
}
}
// The Factory which supports Plugin-Creation
class CookieTinFactory {
public static function getPlugin( $class ) {
try {
return new $GLOBALS['Plugins'][$class]();
} catch( Exception $e) {
// maybe call some default implementation if the mapping is wrong
}
}
}
Show PHP Code (less important part)
Show PHP Client Code
// This is usually in a configuration-file, normally this should
// also sit in a XML structure....
// That's what it would be in 300 days/year
$GLOBALS['Plugins']['CookieTin'] = "NormalTin";
// That's what we have to turn it to before summer :P
if(in_array(date('n'),array(5,6,7))) {
$GLOBALS['Plugins']['CookieTin'] = "DietTin";
}
$tin = CookieTinFactory::getPlugin('CookieTin');
$i=10;
while($i--) {
$cookie = $tin->getCookieInstance();
$cookie->printCalories();
}
A very common use-case for this is the changed behaviour in a testing-environment compared to the production-environment.
There's something else in the example beside the Plugin Pattern - I also made use of the Special Case (the NullCookie) pattern which I'm going to show in a future post....
6/02/2008
Comparing PHP Best Practises
If you're still wondering whether the single- or double quotes are processed faster in PHP you might want to look at phpbench.com. They don't provide any ground breaking new insights, but they show in a very nice way what's best pratice when it comes to arrays, strings and loops...

