HipHop for PHP is not PHP
February 3rd, 2010
Charles Nutter, when talking about Ruby implementation performance, said it best:
Listen, people: Ruby is hard to implement. Oh, it may look easy at a
glance, and you can probably get 70, 80, or even 90% of the way pretty
quickly. But there's some crazy stuff in that last 10% or 5% that totally
blindsides you if you're not looking for it. An early Ruby implementation
has not run that last mile of Ruby implementation, and it takes almost as
much work to get there as it does to run the first 90%.
That goes for pretty much all dynamic languages, including PHP. HipHop is fast by not implementing PHP. It's an implementation of a subset of PHP useful to Facebook. I'm not saying it's not awesome what Facebook has done, I'm just saying don't call it PHP.
Based only on the one limitation they've mentioned publicly, lack of eval(), here's a short list of PHP OSS that currently won't work correctly on HipHop:
- PEAR
- CodeIgniter
- WordPress
- Joomla
- Kohana
I wouldn't be surprised if there were additional features they've removed from PHP in HipHop, their blog post announcing it certainly leaves that possibility open.
So call it what it is, a fast PHP-like language.
The Ruby Trojan Horse: A Look Back at 2009
January 8th, 2010
I’ve been here at Tycoon for well over a year now. I remember thinking out loud about whether or not I should take this job. On that post is a thoughtful reply from the CEO which, while encouraging me to follow my heart, played a large role in my decision to join the team here.
There were some rough patches but, it’s worked out well. They have a tremendous team here and I’m proud to be a part of it. That’s not what this post is about though.
The PHP shop
They were a PHP-exclusive shop when I started. They were more than open to using Ruby though, in fact they seemed to be looking forward to it. However, after a few months of planning and discussion, when it came time to pull the trigger the same old arguments came out. Ignoring what was actually said, a lot of it really came down to conservatism and fear of the unknown. We only had one Ruby developer (me) as opposed to several PHP devs and no one wanted to effectively bet the next several months of the business’ productivity on the new guy.
This is entirely understandable and while I like to think of what could have been, it was the right decision for this company. We split up the work in a way that I still got to do most of my work in Ruby while the rest is PHP. Not a bad deal and it’s worked quite well.
Making inroads
Hey Rich, what do you use to deploy your code?
From that point forward our PHP application was deployed via Capistrano. Very little trouble, it just worked.
Next up, we needed a pretty simple stand alone background worker daemon. A bit of Ruby and the daemons and beanstalk-client gems and we had a worker that’s served us quite well for some time.
The gates swing open
I noticed the migrations in the PHP app were simply SQL files that each developer had to remember to pipe into mysql. So, I wrote a little script, migrate.php, that ran those files for you and kept a schema_versions table maintained with what migrations it had run. This worked great but, honestly, I was a little taken aback by the response:
Can’t we just use Rails’ migrations?
Absolutely. So, I hacked up the smallest possible rails app that still supported migrations and Lou Kosak used some his new found Ruby ability to pare that down quite a bit further by monkey patching Rails.
Now our PHP/CodeIgniter application has it’s database schema managed by Rails migrations and everyone seems happy. We’ve discussed creating a gem for this but, I expect this will be quite a bit easier in the more modular Rails 3.
Next up, we switched from Subversion to Git like the good Rails CodeIgniter application we are. One problem, we used svn:externals pretty heavily and Git submodules aren’t a direct equivalent and feel a bit funky. Lou had an answer in the form of a couple of Rake tasks.
The next big step, that we’re still getting working, is testing. This too, will use Ruby and there’s no wringing of hands.
Every developer here seems genuinely excited about Ruby now. I’m excited to see them learning what I was, admittedly poorly, trying to explain all those months ago. I’m looking forward to a Ruby filled 2010 here at Tycoon.
CI-Events: A Code Igniter event library
January 2nd, 2010
At Tycoon Research we have a significant investment in both Code Igniter and Ruby on Rails. Frequently the differences in methodologies between the two is striking.
We ended up writing quite a few libraries to make CI less painful to develop with while fitting into the CI way of doing things. The CI-Events library is one of those libraries.
Why do you need an event library?
We were running into situations where several parts of our system needed to deal with certain things happening such as user registration.
In that case we were ending up with a Users#create method calling out to many, many other models and libraries or, even worse, handling things unrelated to a User. Over time this can get quite sloppy, bug ridden and difficult to maintain.
An event library allowed for proper separation of concerns resulting in simpler, easier to read code.
Why CI-Events?
We had four main goals:
- Don’t introduce a lot of additional overhead.
- Flexible enough to handle multiple usage styles.
- Fit well into the CodeIgniter way of doing things.
- Considering the indirection involved, attempt to keep things readable.
Admittedly, two of the four are subjective but, with the criteria in mind the other event libraries we looked at failed on one of more of these points. Most significantly, there was no single way of knowing what events were handled by what code.
Another, more minor issue, was the introduction of a new kind of handler file into CI. We felt that was unnecessary.
Usage
The library stores it’s event configuration in a configuration file: config/events.php. The empty config/events.php in the repo contains detailed documentation but, here’s some examples:
For each event there’s an array of handlers. A handler consists of the CI object type, the name of the object, the name of the method and an optional forth argument that may be anything you like.
This approach gives you a few things:
- One point of reference for all the events in your system.
- Delegation of event handling to existing libraries and models where appropriate.
- Reuse of a single handler by modifying the handler’s behavior based on the forth argument.
Sending events is very simple:
The first argument is simply the matching event from your config/events.php. The second argument, like the forth argument in the config file, is entirely optional and may be whatever you’d like it to be. We’ve largely stuck to passing associative arrays through the second argument and been very happy with the result.
Finally, the actual handler:
It’s important to note that all three arguments are optional on the handler methods. If you accept no arguments, it’ll call your method without any arguments. Accept one and you’ll get just the second argument passed to the ->send call. The second argument, when present, will receive the forth argument from the config file. The third and final argument will be the name of the event such as profile.created.
This library has served us very well, in production, for a few months now. Feel free to use it and contribute back if you feel it’s missing something.
Update
I’ve pushed a very simple demonstration application to github. You can find it at http://github.com/rich/ci-events-demo-app. The handler library is simply called Thing and you can see it in system/application/libraries/Thing.php. The event is sent by the default welcome controller. The output looks like this:
Escaping the hell of PHP testing using Ruby
January 1st, 2010
First, some background. Feel free to skip to the next header if you just want the details.
At work, we’re basically a 50/50 environment split between Ruby and PHP. In the last several months there’s been an effort to write more tests for the PHP side of things. We’ve been investigating various PHP testing tools and came to an inescapable conclusion: testing a web app using PHP is not pleasant (I’m being nice here).
I come from the point of view that if writing tests is unpleasant, no one will want to do it. The rest of the team is in agreement so, we had to come up with a different approach.
For some time I was honestly stumped trying to find that silver bullet solution. My answer came at RubyConf talking to Stephen Caudill and Corey Haines. Put simply, doing comprehensive integration testing was better than no testing and I should use Ruby to do that testing.
That was a revelation to me. I hadn’t considered just doing integration test but, during my indecision, we weren’t doing any meaningful testing. So, getting integration testing going and figuring the other layers later, sounded like a pragmatic approach.
Why a new library?
Yes, you can configure webrat to just hit a local webserver and that was my initial approach. This ended up requiring a fair bit of thought and configuration though. This was making testing painful again. I wanted to get to the point that people could checkout the code and not do much more than a handful of commands followed by rake spec.
No webserver or it’s configuration. No complicated webrat or rspec configuration. No test database management nightmares. No nothing. Just simple Rails-style testing.
gem install messiah
Messiah is my attempt at just that. It’s still a very young project and doesn’t hit all those goals yet.
It does however make for a decent first run experience even right now. Messiah itself primarily runs tests that hit php using itself so, it makes for a good demo:
You can see the actual spec file here and the php code it’s executing here.
The only real configuration, in spec_helper.rb, is pretty trivial:
“How’s it work?” or “I love Rack”
The most important part of messiah is a relatively simple idea. I wrote a Rack application that acts as a wrapper for CGI applications. So, it can actually test any CGI app not just PHP apps.
Besides the Rack app, it’s support code for configuring the environment for you at runtime. In the long run, that will be the more important part of messiah.
Where to next?
There are two big things I’m planning on adding in the next several days. First, a set of generators (thanks templater) for adding RSpec, Cucumber and others (preconfigured for messiah of course) to a codebase.
Second, I want to have first class database support. Coming up with a workable solution was surprisingly challenging. You need to consider connecting to the right database, keeping it in a sane state and easy way to work with known data.
My current approach based on database_cleaner, Dr. Nic’s Magic Models and Factory Girl seems to be working out nicely. This is not in the repo yet but, I do hope to push it soon.
How about everyone else out there? Any ideas?
Hoptoad. Goes great with PHP too.
April 9th, 2009
Over the years of Rails work I’ve been using a few services that I consider indispensable now. Hoptoad is one of those tools. It beats the hell out of pretty much every cobbled together error notifier I’ve seen. I can’t see launching an application without it.
The Horror
Sometimes, I need to work with PHP. It’s not pleasant but, there it is. One of the things I did to make this a bit more palatable is hack together a Hoptoad notifier for PHP. Recently, with some help from Lou Kosak, I’ve cleaned the code up a bit and think it might be useful in other projects now.
Grab it
You can find the code at http://github.com/rich/php-hoptoad-notifier. Just drop the Hoptoad.php file somewhere in your include_path and include the following code somewhere early in your application:
require_once('Hoptoad.php');
Hoptoad::installHandlers("YOUR_HOPTOAD_API_KEY");