Friendly Hearts PHP 4
First off, sorry for the low frequency of updates to this blog and website. I promise: API docs are still forthcoming, and I’m planning to put together a second Developer Preview release later this month.
As I’ve mentioned in the About section, support for PHP 4 is one of the major features of Friendly. Most plain-vanilla shared hosting environments offer it, whereas the number of hosts that offer PHP 5 is still relatively small. Unfortunately, PHP 5’s support for object-oriented programming (OOP) — while still not nearly as nice and flexible as Ruby, Perl or even JavaScript for chrissakes — is a lot more advanced than PHP 4’s. And a lot of the things I would like to do with Friendly (like true Active Record-style domain models) that would be clunky-but-doable in PHP 5 are way more difficult, maybe even impossible, when you factor in PHP 4.
To give you one example: there’s a PHP function, class_name, which returns a string representation of the name of a class. So if I had a class called ProductCategory, it would (or should) return the string “ProductCategory,” which I could then use to infer a MySQL table name (such as product_categories) and make some magic happen.
In PHP 5 this works beautifully. But PHP 4 has this little problem where it always returns the class name in all lowercase. Which is no problem at all unless you need to CamelCase a class name as in the example above — PHP 5 would correctly infer the table name as product_categories, whereas PHP 4 wouldn’t know to put that underscore between the words and would return productcategories instead.
The PHP 5 behavior is the behavior I want — it’s the way Rails does it, and it’s the most attractive and readable way to name a table. (If that doesn’t seem important, just wait until you have to spend all day looking at the names in phpMyAdmin.)
So to make models work, it would seem that I’ll have to just do it the PHP 5 way, and warn PHP 4 users that they need to either avoid CamelCasing their class names or specify the table name in a _setup block. That’s a good solution that will work most of the time, although it’s not 100% in line with my philosophy of having Friendly “just work” on older versions of PHP.
I will point out that a similar problem came up during the making of the first preview release, and I was able to work around it by falling back to the URL to get a pre-corrected controller name on PHP 4. I don’t have any such luxury on the models, unfortunately, and on the Friendly-powered site I’m working on right now I’m skipping built-in model support and just making some model classes from scratch. (“From scratch” in this context meaning that I’m not relying on any Friendly ‘magic’ — I’m doing all my SQL queries by hand and just mapping the properties of a Product class to the columns of the products table.)
Which brings me, finally, to the As-Yet-Undocumented Friendly Feature of the Day: any files ending in .model.php (e.g. product.model.php) you place in the app/models directory are automatically loaded when Friendly loads, making those files a great place to stash class or function declarations you’ll need in one or more of your controllers. Unlike Rails, we don’t try to dynamically load models when they’re used (PHP really, really does not support that) so all your model classes would be loaded on each request, but PHP handles that like a champ so there’s no drag on performance as far as I know. (Of course, you’re not limited to classes: on some Friendly sites I’ve used the models folder to store functions as well.)