Sunday, October 9, 2005

Simulating polymorphism in PHP

Today, I was tearing hairs out of my head to find out how to do polymorphism as described by the Liskov substitution principle in PHP (version 4).

The problem I was faced with was the following: I have an object of supertype and I wish to use it as an object of a subtype. Apparently, this is not readily possible in PHP.

I found my answer in a comment to the php manual, credit to Simon Li. It's quite a hack.

What happens is that the object is serialized, it's transformed into a string like this:
string(32) "O:6:"answer":1:{s:6:"answer";i:42;}"
The class name, the third element, is replaced with the class name desired. And finally, the modified string is transformed into a real object again.

I generalized the code from the comment and ended up with following:

// hack to simulate polymorphism in php
// you're not gonna like it
class castable {
  function cast_to($name) {
    $tmp = explode(":",serialize($this));
    $tmp[1] = strlen($name);
    $tmp[2] = "\"$name\"";
    $this = unserialize(implode(":",$tmp));
  }
}

class answer extends castable {
  var $answer = 42;
}

class question extends answer {
  function tell_me_the_answer () {
    echo "The answer is: ";
  }
}

$deepthought = new answer();
$deepthought->cast_to("question");
$deepthought->tell_me_the_answer();

echo $deepthought->answer . "\n";


This outputs:

The answer is 42


No comments: