The problem with PHP

From Slashdot | PostgreSQL Slammed by PHP Creator

Zend’s ZActiveRecord Boondoggle (Score:5, Insightful)
by SimHacker (180785) * on Friday September 15, @02:11PM (#16115256)
(http://www.donhopkins.com/ | Last Journal: Monday February 23, @10:48AM)

The creators of PHP are morons, and their support company Zend is dishonest and incompetent. The ZActiveRecord boondoggle demonstrates exactly what I mean: They can’t program their way out of a paper bag, an don’t even understand the limitations of the very language that they haphazardly “designed”.

It makes me laugh that Lerdorf would slam Postgres, because the PHP designers have no understanding of object oriented programming or databases: instead they invent half baked cargo-cult designs [wikipedia.org], which are naive reactions to other systems they don’t understand: they try to ape their surface features without understanding the reasons behind the way they’re designed.

PHP references [php.net] were thrown in as a band-aid to work around the horrible design flaw that arrays and objects were foolishly DEEP COPIED by default. If you pass or return an array from function to function, its contents are DEEP COPIED, which is EXTREMELY inefficient and leads to all kinds of horrible bugs because it’s the last thing a sane programmer would expect. So instead of fixing the design flaw in PHP, they add “references” that LOOK and SOUND like C++ references, but actually are completely different, again misleading programmers into thinking they understand what’s going on, but working totally differently than a sane person would expect. PHP references are actually half baked symbol table references. The [php.net] sloppy [php.net] implementation [php.net] caused [php.net] many [php.net] bugs [php.net] that [php.net] CORE [php.net] DUMP [php.net] PHP [php.net]! PHP references were so poorly thought out and badly designed, that there were many edge conditions that they hadn’t considered, that simply didn’t work together, caused memory leaks and core dumps, and had useless and confusing semantics: callers passing references, functions declaring that they take references, functions returning references, etc. Compare that to C++’s simple and consistent definition of references in term of pointers. The only way to make a PHP reference to an object is to put it in a variable — you can’t make a reference to a field of an object or the return value of a function without storing it in a temporary variable — totally unlike C++, and totally stupid.

PHP’s object oriented programming system is a half-baked imitation of C++’s object model, haphazardly designed by charlitans who had no clue about the fundamentals of object oriented programming, elegant language design or efficient implementation. First of all, if you’re going to try to imitate an existing design without understanding it, then for god’s sake, at least imitate a language whose object system doesn’t suck, and a language that has similar semantics to the language you’re trying to kludge. C++ is a static compiled language, and its object system deeply reflects that fact. (That is to say, there’s very little reflection beyond RTTI, because the compiler throws all the interesting stuff away! And C++’s oop design had to make many horrible compromises because the C++ object system was designed to map directly into C semantics [since the original C++ compiler compiled C++ into C.]) Most of those C++ design decisions make absolutely no sense for a dynamic interpreted language like PHP. (Many of them made very little sense for C++ itself, but even less sense in the context off PHP.)

One prime example of how PHP screwed up its object system, is that they blew it on static methods, in a way that makes it impossible to properly implement an ActiveRecord-like ORM (among other useful things). A static method defined in a base class can be called from a subclass, of course. But the “this” of the static method in PHP is (accidentally but incorrectly) defined to be the base class in which it was defined, not the subclass on which it was actually invoked as you’d expect. So static methods have no way of telling the class from which they’re actually called. “Why would you ever want to know that?”, you might ask, if you’re new to object oriented programming. Because that behavior is necessary to implement many standard object oriented programming patterns, such as Martin Fowler’s “Active Record” pattern [martinfowler.com], which is so popular with the Ruby on Rails folks.

So eventually, Zend figures out that they’re losing PHP programmers in droves to Ruby on Rails, because of its easy to use and understand ORM called ActiveRecord, so their natural reaction is to try to ape the surface features of Ruby on Rails without understanding it, just the way they’re been aping every other technology they kludged into PHP.

Zend published a screencast demonstrating their answer to Ruby on Rails, which they predictably called “ZActiveRecord”, a textbook case of cargo cult design, half-baked vaporware, insincere marketing and faking demos. They didn’t even understand the flaws in THEIR OWN language’s object system well enough to know that they couldn’t do what they promised to do in PHP. They announced with great fanfair that ZActiveRecord would be the official ORM of Zend Studio, before they even figured out how to implement it. Then somebody pointed out it was impossible to implement ZActiveRecord as Zend designed (and pretended to demonstrate). But that didn’t stop them from giving bogus examples of fake code in their dishonest screencast:

class Person extends ZActiveRecord {}
$people = Person::findAll(array(‘nameFirst’ => ‘Daniel’));

foreach ($people as $person)
{
echo $person->nameFirst . “n”;
}

Well guess what? They got called on it:
ZActiveRecord Can’t Work [joshuaeichorn.com]:

In the webcast the following active record example was shown. This looks nice and slick but I don’t see how its possible, at least in php 5.1. There is no way to get the class name of the child in in the find all method. This example shows how get_class doesn’t help it always returns parentstatic. Anyone have a clue on how Zend is planning to get around this problem. From what I can tell its impossible and I haven’t seen anything on 5.1.2dev that would solve the problem but I could just be missing something and there is an easy way around the problem. To me it looks like PHP forces you to do a none static activerecord implmentation.

There is a long-standing bug in PHP that prevents this obvious approach from working:
Bug #30934: Special keyword ‘self’ represents the parent class instead of the child class when it is used in an inherited method of the parent class. [php.net] The fact that the supposedly “expert PHP programmers” at Zend themselves got tripped up on this bug proves that it’s a severe source of confusion and a bad design, but they continue to deny there’s a problem, and have quietly shelved their plans for ZActiveRecord, instead of fixing their own fucking bug.

Some comments on the bug that prevents anyone from writing an ActiveRecord-like ORM in PHP: I agree, this is damn annoying. However, I’m sure the PHP team will come back saying “Sorry this is not a bug, it’s an undocumented feature”. … It would be so nice if this can be fixed, but I have a nasty felling people have to live with this :( … What is also most annoying is this doesn’t just affect constants, it
affects anything that can be static, that is constants, class members, and methods. … Sorry, you have a complete wrong idea og OO programming. Static methods are bound/resolved at compile time. That is the compiler can replace self with the current class. … So, it appears as it is a limitation of the compiler and the entire object model. I think such behavior makes inheritance of static methods useless because even if a static method is inherited, it still functions as inthe class where it was declared. Moreover, inherited static methods are using the static properties which were declared in the parent class but not the inherited one. … Does anyone whats happening with this bug? Is it going to be fixed or are the PHP devs just ignoring it? Unless this is fixed (or a suitable workaround is added) I cannot put common code that refers to static variables or methods in a base class, resulting in significant code duplication. This is a huge issue, and is a perfect example of why PHP is regarded with contempt in many circles. … Third to allow what you need a major change is needed that would slow down php – every part of php code execution. And that will take a while.

And here’s the final word from andi: Thank you for taking the time to write to us, but this is not a bug. Please double-check the documentation available at http://www.php.net/manual/ [php.net] and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php [php.net] This is expected behavior. self:: binds statically to its class (to the best of my knowledge other languages like C++ don’t support this either as they require to explicitly use the class name). There are actually advantages also to this approach as they allow you to protect and
encapsulate functinality.

Talk about being hoisted on your own petard [blogspot.com].

-Don

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Comments are closed.