PHP and ActiveRecord (continued)
Today I saw a big traffic increase from my PHP and ActiveRecord post. It looks like PHPDeveloper posted a link to the article and response, so I’ve written a response to the Arnold’s wor(l)ds response post. Arnold’s post is insightful, references runkit and has a good implementation of a Sortable tasklist example in PHP.
In Ruby everything is an object. A Ruby object that is.
When I was working on Biscuit I longed for a working implementation of runkit. I experimented with it and it did offer exactly what I wanted but it lacked widespread deployment because of and stability. After two years I don’t think much progress has been made (not to take anything away from the author). I think runkit is a hack, a dangerous one too. Here is another example of why Ruby is better.
In PHP if you want the features runkit offers (add super globals, modify class methods at runtime, etc.) you have to hack the engine at the internal C/C++ level, meaning you have to completely control the development, testing and production environments, track source changes, hope nothing breaks… You might as well be forking at that point.
If you want to hack something in the Ruby kernel methods, you just monkey patch – equally dangerous on kernel methods BUT limited in scope…in Ruby you’re not destroying Ruby with monkey patches. You might kill your own application but other applications that don’t share the same instance are not effected.
Lineage
PHP and Ruby have a lot in common, they both derive a certain expressiveness found in Perl, and they are scripting languages with low overhead and a quick learning curve. They’re also different in a number of ways, and I think that can be chalked up to lineage. One could argue that PHP’s design is derived from C++ and Perl and maybe even Java lately.
One would also be able to argue that Ruby derives its design from Smalltalk/Strongtalk and Perl. So the reason a lot of PHP users probably like Ruby is it’s light weight scriptyness and Perlish feel (I know I’ll take crap from Perl, PHP and Ruby developers for that one). But because of the lineage we see straight line inheritance and interfaces in PHP and in Ruby we see mix-ins. Back to Arnold’s article.
How to not write a shitload of code using Ruby Mix-Ins
Arnold next addresses the issue with mix-ins showing his implementation of a sortable class in PHP. His implementation is good but it’s a lot of work compared to just expressing acts_as_list in Ruby. Most people might see this as splitting hairs but it’s not for anyone actually wondering. In Ruby you need exactly 1 (user) class to handle this sort of functionality – the difference being that the Class is the list in Ruby.
In the PHP example you need a TaskList and a Task and since Sortable is only an interface you’ve actually got to write the methods to implement them in your own (user) class. Again, you’re saying “big woop”...well the woop is the fact that you can’t do mix-in style inheritance like this because your class needs to inherit the methods to make them work anything like acts_as_list, ie. by not writing a shitload of code for every sortable class.
The second example demos a sortable runkit implementation. This is really similar to saying PHP6 will have the keyword static to solve the issue with static property inheritance.
The problem with static inheritance in PHP
I’ve seen people describe static property inheritance as a problem, and I’ve probably been guilty of it myself. Well it’s not really a problem. Static properties shouldn’t inherit. The PHP developers have said time and time again they are not changing this, it works how it is supposed to work.
As far as runkit goes, It seems pretty crazy to have an engine level hack + runtime interferance with a class to overcome this issue.
Over and over again when I see this coming up as an “issue with PHP” I remember grappling with it with Biscuit. The theme that I keep seeing when people try to describe this problem has to do either with identifying the calling class using an inherited static method. In other words, people are usually trying to do this:
Class Base {
static public name() {
return get_class(self);
}
}
Class My Extends Base { }
echo My::name(); #=> Base but everyone wants My
They’re usually trying to implement some form of ActiveRecord a factory method or something similar. From what I’ve seen on how PHP6 will be re-using the static keyword and implementing namespaces this problem won’t be fixed like I had hoped.
What PHP6 Actually Needs
There’s an article entitled What PHP6 Actually Needs and you could almost retitle the article Things Ruby has and PHP doesn’t. So if some many good programmers are asking for these features why aren’t they getting them from Zend and PHP6?
A question that Ruby enthusiasts might ask is why are so many PHP developers asking for these features and still not using Ruby??? I think for Ruby it has a lot to do with deployment issues – fast_cgi sucks, ligthttpd you have to jigger with, mongrel and just about every other deployment solution is akin to setting up an application server. For smaller apps that a lot of PHP developers work on having to go through this crap just for a small program is prohibitive.
So I guess this continuation of the original article seems like an attack on PHP. It’s not…it is a continuation about why ActiveRecord works really well in Ruby and not so good in PHP. But there is hope. After looking at the Row Data Gateway pattern I’m thinking a really good implementation can be done in PHP that would give similar flexible muscles for PHP database driven development.
Trackbacks
Use the following link to trackback from your own site:
http://www.actsasflinn.com/trackbacks?article_id=php-and-activerecord-continued&day=10&month=08&year=2007


