Today I read an article about how Active Record is implemented in Ruby. In this article he lays down how things are done in Ruby and how that is not possible on PHP. Though I agree with him on a large part, there are a few site notes to make here.

First of all it is possible to add methods to an existing class. There has been an extension called runkit out for years. But so little people have shown interest in it, that it has never grown out of the experimental stage.

If I understood the Ruby code correctly, acts_as_list specifies that the item is part of a sortable list with the position of the item known to the object. The has_many specifies that the object has a list with children. To translate this to PHP, you should be able to do something like:

1
2
3
4
5
  $list = new TaskList();
  $list->tasks[] = new Task('Buy bread');
  $list->tasks[3] = new Task('Become a famous');
  $list->tasks[] = new Task('Have a succesfull blog');
  $list->tasks[4]->setIndex(2);
  $list = new TaskList();
  $list->tasks[] = new Task('Buy bread');
  $list->tasks[3] = new Task('Become a famous');
  $list->tasks[] = new Task('Have a succesfull blog');
  $list->tasks[4]->setIndex(2);

Something like this can be done in PHP, though you’ll need to write some code to get it done. As a prove of concept I’ve just written an interface and a class to do this.
[snip php-source]code/sortable/sortable.php[/code]
And a small test.
[snip php-source]code/sortable/tasklist.php[/code]
See it working

We can directly see a few problems here with this approach. First and least important, the fact that you need to walk trough the complete array each time isn't helping performance. But more important, because the key is stored in the object, there is no guarantee that is is unique, hence the warning. I don't know the solution Ruby has for this, but I can imagine that you want to increment all the other keys. Since there is no connection from the Task object to the SortedList, there is no good way to solve this. At least not without using experimental stuff like runkit.

With runkit we can rename to function and add a new function with the old name. In that new function we will call the old function and add something extra. This all is standard practice in C/C++ and javascript, but not so common in PHP. Java solves this differently (and a bit more structured) with AOP. I know PHP also got an AOP solution, that is probably even less used that runkit.

[snip php-source]code/sortable_rk/sortable.php::php]
[snip php-source]code/sortable_rk/sortedlist.php::php]

Unfortunately I can't show this working on my blog, since this server doesn't support runkit. That also shows why this never could be part of any general framework. Runkit is just to advanced and dangerous, it not installed here since it occasionally causes seg faults (ouch), so most users don't have access to it. This does proof however that this can be easily done in an extension defining an interface and a class.

So there is a mixed conclusion here I think. First of all, solve thing in PHP in a PHP way, calling methods in a constructor to modify the object and defining relationships between classes, just isn't the way PHP works. If you like that stuff, Ruby is the way to go, it's simply to magic for PHP.
Second, there are problems like these, which have simply been stamped as impossible, accepted and forgotten by the PHP community. But if we look at other languages, we see that there is much to be gained.

My personal conclusion: I see that I'm not the only one with the need for some more advanced OO stuff. Though I already would know where to find more time, I'll start on making an EPL (Extended PHP Library) extension. Who needs sleep anyway :p. (And hopefully than I'll finally get a spot on planet PHP.)

Download the code

  4 Responses to “PHP != Ruby (and why PHP needs more advanced OO stuff)”

  1. Hey thanks for the response, I found it pretty insightful. I’ve written a response to your article here: http://www.actsasflinn.com/articles/2007/08/10/php-and-activerecord-continued

    Sorry for the lack of comments on my site, gotta keep the spammers at bay.

    Cheers,
    Flinn

    ReplyReply
  2. ruby is great. It is object oriented.

    ReplyReply

 Leave a Reply

(required)

(required)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code lang=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" extra="">

   

Questions? Just ask!

About the author

Hi, I'm Arnold Daniels. How nice that you like to know a bit more about little old me :).

I've spend a big part of my life behind a computer (and not playing games). I've learned a lot about databases, programming and system administration especially on. the LAMP stack (Linux, Apache, MySQL & PHP).

Have a look at what I'm working on now!
© 2012 Jasny · web development Suffusion theme by Sayontan Sinha