Mercurial

July 30th, 2008

Using a distributed version control makes things really easy (sometimes). Having several branches and merging between the branches is like playing super mario. For example if you have three branches:

  1. project-dev
  2. project-qa
  3. project-stable

Using mercurial every branch would be a clone of each other. Pulling and pushing between the branches now looks like this:

CODE:
  1. cd project-dev
  2. pull ../project-stable # mmh get be a the bugfixes from stable

or

CODE:
  1. cd project-qa
  2. pull ../project-dev # get my awesome new feature to QA

Easy huh. But there are also some flaws. Sometimes it happens that a pull results in multiple heads now you will have problems to commit your uncommited changes. Multiple heads are nod bad per se. Then hg tool will recommend you to use "hg update -C" - never ever do this. It will weep out all your uncommitted changes and erase your work. Instead run "hg head" to find out the most actual revision (btw it's always called "tip"). Then merge with "tip" using "hg merge tip". Then commit your changes. Everything of your is save now. Now we try to get rid of our multiple head hydra. Run "hg head" again. Find the other revision (e.g. 128) and merge it "hg merge 128". Then commit it "hg ci -m 'killed the hydra'" and push it. Tada.

Other usefull commands:

"hg pull -u" - Pull and update
"hg fetch" - Pull, update and merge (needs to be activated through extension)

PHP: Short Syntax for Arrays

May 28th, 2008

Especially when you develop frameworks you have often the problem to deal with different configuration issues. Image this:

PHP:
  1. function foo($necessary_param, $optional_param1 = 0, $param2 = 1, $param3 = 2) {
  2. ...
  3. }
  4.  
  5. // let's overwrite the third optional parameter
  6. foo('bar', 0, 1, 69);

In PHP there is no such thing as named parameters - so we have to help ourselves:

PHP:
  1. function foo($necessary_param, $optional_params = null) {
  2. if(is_array($optional_params)) {
  3. if(isset($optional_params['param1'])) ...
  4. if(isset($optional_params['param2'])) ...
  5. if(isset($optional_params['param3'])) ...
  6. }
  7. ...
  8. }
  9.  
  10. foo('bar', array('param1' => 0, 'param3' => 4));

Hopefully you get the point here - nicer would be:

PHP:
  1. foo('bar', ['param1' => 0, 'param3' => 4]);

Especially when you go for nested arrays this syntax becomes more readable and even more maintainable. Lucky me, that there's a patch for a short syntax for arrays provided by Ryusuke Sekiyama.

I've written down a RFC about "Short Syntax for Arrays". If you like it support the RFC and drop me a note.

Traits for ActiveRecords next TopModel

May 18th, 2008

In this post, two possible implementations of the ActiveRecord design pattern will be discussed. With the raise of Ruby on Rails, ActiveRecord became very popular to the IT crowd.

To put the concepts of this pattern in a nutshell:

"ActiceRecord = Data + Business Logic."

An ActiveRecord object maps a row in a database table to an object in your webapplication (Data). This record is flavoured with object logic and even some domain logic (Business Logic). I won't repeat too much details as the ActiveRecord pattern is exhaustive discussed elsewhere.

As introduced in Rails, all the object relational mapping code is encapsulated in a very powerful ActiveRecord base class. Following the convention over configuration paradigm, you derive your model from this base class - having all the power of a database at your fingertips.

Implementing the ActiveRecord design pattern in PHP is not very easy. There have been many attempts by various frameworks but none of it has an elegant implementation like in Rails. Flinn Mueller pointet out that because of a lack of PHPs language core features it is impossible to create an such an elegant implementation.

Using the AR pattern typically looks like this:

PHP:
  1. class Blogentry extends ActiveRecord {
  2. }
  3.  
  4. $blogentry = new Blogentry;
  5. $blogentry->title = "Pac Man eats my Panties!";
  6. $blogentry->save();
  7.  
  8. $otherentry = Blogentry::find_by_id(3);
  9. var_dump($otherentry);

Usually the save or find_by_id method is implemented in the ActiveRecord base class. Before we had Late Static Binding (arrived in PHP 5.3) it was almost impossible to have a nice implementation of this pattern. E.g. when you call Blogentry::find_by_id(3), which is implemented in the ActiveRecord base class, it is impossible to derive that the method is statically invoked by the derived Blogentry class.

First I'm going to show you the LSB based implementation:

PHP:
  1. <?php
  2.   class ActiveRecord {
  3.     static function find_by_id($id) {
  4.         $class = get_called_class(); // LSI magic comes from here
  5.         $sql = 'SELECT FROM `' . $class . '` WHERE `id`=\'' . $id"';";
  6.         echo "Generate sql for select by id\n";
  7.         echo $sql . "\n";
  8.         return(new $class);
  9.     }
  10.    
  11.     function save() {
  12.       $class = get_class();
  13.      
  14.       if(!isset($this->id)) {
  15.         echo "Generate sql for new Record:\n";
  16.        
  17.         $sql = 'INSERT INTO `' . $class . '` ';
  18.         $sql_fields = '(';
  19.         $sql_values = '(';
  20.         foreach($this->fields as $field => $type) {
  21.           if($field != 'id') {
  22.             $sql_fields .= '`' . $field . '`,';
  23.             $sql_values .= "'" . $this->{$field} . "',";
  24.           }
  25.         }
  26.         $sql = $sql . substr($sql_fields, 0, -1) . ') VALUES ' . substr($sql_values, 0, -1) . ');';
  27.         echo 'sql: ' . $sql . "\n";
  28.         $this->id = 1;
  29.       } else {
  30.         echo "Generate sql for Update:\n";
  31.        
  32.         $sql = 'UPDATE `' . $class . '` SET ';
  33.         foreach($this->fields as $field => $type) {
  34.           if($field != 'id') {
  35.             $sql .= '`' . $field . '`=\'' . $this->{$field} . '\',';
  36.           }
  37.         }
  38.         $sql = substr($sql, 0, -1) . ';';
  39.         echo 'sql: ' . $sql . "\n";
  40.       }
  41.      
  42.     }
  43.   }
  44. ?>

The magic lies in the get_called_class method - this function returns the class where the function was statically called from.

This is quite elegant but it brings up some problems. As mentioned in Kores rant "Why Active Record Sucks", deriving your model from an ActiveRecord base class will disturb your code semantics.

To solve this problem I used the very promising Traits patch from Stefan Marr. Traits are like interfaces with code - by using them, you can simulate multiple inheritance (Ruby has a similar concept called mixins). And here comes the beef:

PHP:
  1. <?php
  2.   trait ActiveRecord {
  3.     static function find_by_id($id) {
  4.       $class = get_class();
  5.       $sql = 'SELECT FROM `' . $class . '` WHERE `id`=\'' . $id"';";
  6.       echo "Generate sql for select by id\n";
  7.       echo $sql . "\n";
  8.       return(new $class);
  9.     }
  10.  
  11.     function save() {
  12.       $class = get_class();
  13.      
  14.       if(!isset($this->id)) {
  15.         echo "Generate sql for new Record:\n";
  16.        
  17.         $sql = 'INSERT INTO `' . $class . '` ';
  18.         $sql_fields = '(';
  19.         $sql_values = '(';
  20.         foreach($this->fields as $field => $type) {
  21.           if($field != 'id') {
  22.             $sql_fields .= '`' . $field . '`,';
  23.             $sql_values .= "'" . $this->{$field} . "',";
  24.           }
  25.         }
  26.         $sql = $sql . substr($sql_fields, 0, -1) . ') VALUES ' . substr($sql_values, 0, -1) . ');';
  27.         echo 'sql: ' . $sql . "\n";
  28.         $this->id = 1;
  29.       } else {
  30.         echo "Generate sql for Update:\n";
  31.        
  32.         $sql = 'UPDATE `' . $class . '` SET ';
  33.         foreach($this->fields as $field => $type) {
  34.           if($field != 'id') {
  35.             $sql .= '`' . $field . '`=\'' . $this->{$field} . '\',';
  36.           }
  37.         }
  38.         $sql = substr($sql, 0, -1) . ';';
  39.         echo 'sql: ' . $sql . "\n";
  40.       }
  41.      
  42.     }
  43.   }
  44. ?>

You simply add your functionality to your class by using the trait:

PHP:
  1. class Blogentry uses ActiveRecord {
  2.   public $fields = array(
  3.     'id' => 'int',
  4.     'title' => 'varchar',
  5.     'text' => 'text',
  6.     'created_on' => 'datetime'
  7.   );
  8. }

I think the implementation with traits is much better than with late static binding because you don't have to worry about your code semantics and (almost) no need for magic functions (if you dig deeper into AR - say hello to __callStatic).

I hope that the trait feature will soon be added to the PHP Core.

Disclaimer: These examples are just Proof-Of-Concepts there is no database driver implemented yet. Currently we are working with PHP bleeding edge to have a tight implementation of a state of the art web framework. You can check it out at google code - but the current state is far from beeing stable.

PHP Unconference 2008

May 6th, 2008

Last weekend, Dennis and I attended the PHP Unconference 2008 in Hamburg. We were very curious to see where the PHP community is heading to, keeping in mind that there is a quite loud debate going on about future enhancements. Some people want to see the PHP language getting closer to Ruby or Python, allowing more elegant code while other want to stay still on keeping it simple.

Unfortunatly, we were not able to reveal our opinion on this matter properly, as we came to late to our own session - due to damn german weekend traffic jams. However, during the in-between debates, we took position for extending the core of the PHP language so that it can compete with Ruby or Python. Our opinion emerges from our own experience: we are developing projects in all languages; PHP (large scale projects), Python (mid-size projects), and Ruby (prototyping, internal software). While we appreciate the scalability and relative straight forwardness of PHP, we miss the elegance and handiness of Ruby (and Rails) and the perfomance aspect of Python. Sure, we all have to compromise at a certain point, neverthough you must at least try to get rid of things that are bugging many many people among the PHP community. It's open source dude - everybody is (can be) responsible.

While attending the "Ask the core developer" Session by Johannes Schlüter, which was definitely a highlight of the Unconference, we understood that one of the most fundamental problems is that every released unofficial patch can cause trouble in other PHP components or modules. That's why testing on a larger scale is essential for further enhancements of PHP. Hence, we welcome the idea of the upcoming TestFests, where we expect some nice results. We will soon reveal some results of our "playing around" session with the PHP core - we like coding much more than wining around ;)

From Subversion to Mercurial (or GIT)

May 6th, 2008

Lately we switched our major projects from a centralized version control (Subversion) to a distributed version control (a land were complex branches are not pain in the ass). We went for Mercurial instead of GIT. Some reasons for this decision could be read here - but the main reason for us was that because Mercurial was programmed Python we could use its libraries directly in our projects.

Update: Seems that other people also favour mercurial instead of git - but the crows is on github.

Memcached on PHP 5.3 (on Vista)

April 21st, 2008

While installing memcached on my ubuntu workstation and making it run with php5.3 (and the correct PECL extension) was pretty easy - I really got an headache installing it on my Vista Machine. Installing memcached for Win32 was the easiest task, because there are good binaries which can be downloaded here (hint: you can't install it on Vista with the normal user rights - you have to start "cmd" as Administrator Ctrl + Shift + "Cmd" + Enter).

But installing the PECL extension was difficult - PECL4Win does not contain a correct build for PHP 5.3. A few hours later I found an unofficial build here - but in the beginning that doesn't work. PHP was neither providing me a descend error message nor was the extension working. I analyzed the .dll with the dependency walker and found out that there are two release versions: normal and thread safe. After using the thread safe version everything worked fine.

[update: a similar strategy was burried in the comments of PECL4Win - maybe they should improve their documents]

The Expando Class

April 21st, 2008

Fooling around with my google app engine account, I found this following very appealing Expando Class. Basically, it behaves like a model but it has dynamic fields. This is superb - having all the strength of a database on some fixed fields, but being able to extend the model through dynamic structures will provide you a lot of supercowpowers.

You could use this exensively in Content Management Systems, where a page consists of a certain datastructure (which is occasionally not really known before). You would save the way the data should behave in a Prototype Model and the data itself in, let's call them, Pages. The space that will be used for the database is now effeciently used. Whether your Page just contains a headline and a text, or it is
a full blown wikipedia page with special side contents and different other relations. No more NULL-able fields in relational databases - no more JOIN orgies for normalization lovers.

The only other database that I know which follows such paradigms is CouchDB (written in Erlang) - which goes a step further by having a built-in versioning system for all data objects. But this is actually a nicetohave because it should be easy to implement in GSQL as well.

Migrate Prototype to jQuery (quick’n dirty)

April 17th, 2008

In out latest project we had to migrate Prototype to jQuery within a very short period of time. Both libraries were used in that project and we had to get rid of one of them to save bandwidth and client calculation power (prototype is about 95kb heavy javascript code).

Let's start nice and easy. First of all, people want that jQuery nicely coexists with prototype. In fact, that's very easy to realize, because jQuery has got a built-in compatibility mode. You simply have to call:

JAVASCRIPT:
  1. jQuery.noConflict();

The next thing are the selectors. Prototype select DOM Nodes by the $ shortcut function which takes the id as parameter. jQuery has a slightly different approach, it uses XPath and CSS Selectors to address (even multiple) elements.

That is, in Prototype you say $('foo') (will select the element with the id 'foo). In jQuery you say jQuery('#foo') - the main difference is, that the prototype function will return an HTML Object, the jQuery will return (wait for it...tadaaa) a jQuery object (read more on the chaining programming paradigm). To obtain the HTML Object you have to add .get(0) to the jQuery selector, this will retrieve the first HTML Object.

so:

JAVASCRIPT:
  1. $('foo')
  2. $(target_id)

will be written to:

JAVASCRIPT:
  1. jQuery('#' + 'foo').get(0)
  2. jQuery('#' + target_id).get(0)

To ease that codemonkey work we created a regular expression which searches for the prototype pattern and replaces it with the jQuery pattern:

Search: $\(([^)]+)\)
Replace: jQuery('#' + \1).get(0)

The next issues must sadly be addressed manually.

All code with Ajax. must be rewritten with the jQuery.ajax function.
All Event. code must be rewritten with the jQuery.bind function.
All Form. code and den $F helper functions must be rewritten using the jQuery.Form plug-in.
All script.aculo.us Effects were rewritten using jQuery Effects.

And last but not least, a very tricky one: Prototype uses a bind method, to bind the scope of an object to a function. In jQuery there is not such a method - because there's no need of it, the jQuery.bind is strong enough. But when you have to interact with other libraries - in our case Google Maps, we need it. So we have to write it by ourselves:

JAVASCRIPT:
  1. Function.prototype.bind_scope = function (object) {
  2. var method = this;
  3. var wrapper = function () {
  4. var args = Array.prototype.slice.call(arguments);
  5. return method.apply(object, args);
  6. };
  7. return wrapper;
  8. };

You can read more on that topic here. Sure there is a lot more to take care of. Sure you can rewrite your code better e.g. by accessing css properties through jQuery.css or input values through jQuery.val. But to solve the problem in a short time this is a good start.

Google App Engine

April 17th, 2008

Yiiiiha. My Google App Engine Account has arrived - many thanks to Gregor Hochmuth. Google App Engine is a hosting platform for Python Web Applications. The clou is that you don't have to worry about scaling your application, because you will utilize google's infrastructure.

"What's the gotchas?"

Unlike Amazons EC2, which is able to host everything, Google App Engine is python only. No Ruby. No PHP. Some of you will love it, some of you won't care, some of you will super-hate it. The second point is, that you have to use google's own database engine, which does a good job on scaling, but it is not as flexible as it should be. But there are some other nice benefits like an already built in authentication system with your gmail account and a very elegant API to interact with almost every google service.

We keep you informed what little project we gonna kick on that platform.

Trouble with ActionMailer on Rails 2.0.2

February 25th, 2008

Rails 2.0.2 was released two months ago, and the rails wiki is partially still not up-to-date. So when I tried to set up an ActionMailer by this guide, I ran into serious problems.

The wiki article says, that you can configure your ActionMailer by putting the following code within the configuration block at the environment.rb:

RUBY:
  1. ActionMailer::Base.smtp_settings = {
  2. :address  => "smtp.postoffice.net",
  3. :port  => 25,
  4. :domain  => "www.mywebsite.com",
  5. :user_name  => "me@postoffice.net",
  6. :password  => "mypass",
  7. :authentication  => :login
  8. }

Well, that is not exactly what it has to look like nowadays. So listen up: if you are using Rails 2.0.2 and got trouble with ActionMailer during server startup (especially with "uninitialized constant ActionMailer (NameError)"), try to setup your ActionMailer configuration as follows:

RUBY:
  1. config.action_mailer.smtp_settings = {
  2. :address  => "smtp.postoffice.net",
  3. :port  => 25,
  4. :domain  => "www.mywebsite.com",
  5. :user_name  => "me@postoffice.net",
  6. :password  => "mypass",
  7. :authentication  => :login
  8. }

So this is how it worked for me. Nothing changed except for the first line. Instead of calling the ActionMailer in a static way, you put your configuration into config.action_mailer.