Tag Archives: rowdatagateway

Model-View-Controller in PHP: Model

(Notes:

)

I have one thing to say for all of those PHP developers who look at Rails’ ActiveRecord class and get all excited about implementing it in PHP:

It can’t be done.  Yet.

Here’s why:

Until PHP5.3, PHP does not implement a feature called “late static binding”.  What is late static binding?  Well, how about I show you what it’s like to NOT have late static binding:

class A {
   public static function who() {
     echo __CLASS__;
   }
   public static function test() {
     self::who();
  }
}
class B extends A {
  public static function who() {
    echo __CLASS__;
  }
}
B::test();  //Outputs:  'A'

That’s right:  B::test() outputs ‘A’.  This is a problem, because while it is true that B is a subclass of A, B is still B.  When I call a static method of B, I want it to know that it’s B.

With late static binding (only available in PHp5.3 and onward), this goes away:

<?php
class A {
  public static function who() {
    echo __CLASS__;
  }
  public static function test() {
    static::who(); // Here comes Late Static Bindings
  }
}
class B extends A {
  public static function who() {
    echo __CLASS__;
  }
}
B::test();  //Outputs 'B'
?>

Why is this a problem for ActiveRecord?  Well, say we define a class called ActiveRecord, and create a subclass of ActiveRecord called Person.  When I call Person::find_all(), PHP5.2 is going to run find_all in ActiveRecord – and ActiveRecord’s find_all() will not know what kind of subclass I am.  It won’t know if I’m a Person, Dog, Pizza, or any of that jazz.  Essentially, ActiveRecord is now dead in the water.

Now, you could just make find_all a standard method instead of a static one, but then for every find operation, you’d have to do this:

$p = new Person();
$persons = $p->find_all();

Semantically, this doesn’t make much sense.

But, PHP coders, take heart –  there are two silver linings: