Saturday, September 16, 2006

Ruby on Rails and PHP

The first thing to keep in mind when trying to form a comparison between PHP and Rails, is that PHP is just a language. It’s a scripting language that has a lot of useful functions that make adding dynamic content to web pages easier than its predecessors. What PHP is not (and what Rails, in fact, is) is a framework. In software terms, frameworks are generally tools and pre-built objects that help you create a solution faster by not reinventing the wheel.

More specifically, Rails is a full-stack framework. Full-stack basically means that when you decide to use Rails it will provide practically all of the tools necessary all by itself. While you are welcome to use other tools for sections of Rails’ functionality, most current Rails developers are not (and for obvious reasons described below).

So PHP is just a language. When you choose to use PHP to build a significant web application what you’ll want to do is look for tools and pre-built objects that are written in PHP. Some are packaged together in frameworks. Other times you’ll assemble them ala cart (a database abstraction layer here, a template system there). Sometimes building systems this way makes a lot of sense, but other times the overhead of divided tools makes for more work than it might be worth.

In Rails, they follow a mantra of “Convention Over Configuration.” With this in mind, Rails will follow industry conventions to make your job easier whenever possible. One example where you can see this in action is with page templates.

In Rails, if you have, for example, a BlogController and it has a method called list, Rails will automatically use the list.rhtml file inside of a folder called blog in your views folder. Not only that, but Rails will automatically pass on any instance variables you were using in the controller so that the view has access to them.
Now, when I am doing something similar in my own PHP apps, I have to manually instantiate the template object, manually pass references to any variables I know the view will be interested in and then manually tell it what template file to use. While all that manual code is pretty simple and easy to write, on even medium-sized apps it starts to take a toll on the leaness of the codebase.

It will follow obvious conventions when possible but allow you to override the convention with a specific command; in this case to use a template file other than list.rhtml if needed.

We will move further in more detail:

Ruby is a fun and interesting language in its own right; however, it has gotten a lot more spotlight these days, specifically because of Rails. So, if you are using Rails you’ll be writing Ruby code, and now it’s time to compare some aspects of Ruby to PHP.

For me, the biggest difference between Ruby and PHP is that Ruby is an object-oriented language throughout, while PHP’s object model feels more like an afterthought. In Ruby everything is an object, while in PHP most everything is a native variable type.

I’ve been using object-oriented design exclusively for a few years now, and while I continue to model my PHP web applications with objects, they can be very awkward at times. When this happens I’m usually forced to jump back to procedural programming to do things like iterate over a collection of objects. Iterators, by the way, are very cool in Ruby. For example, in Ruby I can do something like:
employees.each {employee employee.give_raise}

That .each statement lets me iterate over the collection and then use the reference between the pipes as a way to perform actions onto the object. In this case, giving each employee a raise.
In PHP few things are objects by default, including collections. Instead, there is a native array type and a bunch of functions that you can pass an array to that do something of interest. For small scripts this doesn’t bother me, but for my bigger projects it’s a real pain. Early on I even considered writing my own array object. I quickly let the idea die when I came to realize I’d have to pass out native array types to the various tools (like Smarty and a number of other PEAR Objects) anyway, as that’s what they knew how to work with.

So those are some of the biggest reasons why most of people starting to prefer Ruby over PHP, but this comparison still has one more part: deployment. What good is an app if you can’t put it onto a production server?

Deployment of ROR :

If there is one thing that has me down on Rails it’s deployment. When I say deployment I don’t actually mean the act of uploading a new release. That’s actually very easy to do with a tool called Switchtower. No, I’m talking about using a shared-hosting provider. Dedicated hosts are easy to get going with Rails, but when you are using a shared box there is a little more to take under consideration. Let me explain.

The first reason why shared-hosting environments are tough is simply because Rails is still so new. PHP was the same way when it first started getting popular. These days however, I’d be shocked if any shared-hosting environment didn’t offer some level of PHP support. The second reason is because running a Rails application properly requires more resources and power given to the users on that shared box. Because of this most system admins of shared-hosting setups are rightfully cautious.

I can’t say I know exactly why Rails needs so much more “oomph.” The big thing to keep in mind is how most CGI environments work. The web server will normally build up the environment for the CGI, execute the code, return the HTML that was built to the client and then destroy the environment. It does this every time a request comes in. Now, it could be that Ruby is a little slower than PHP, but I suspect the main bottle neck is something else. If I recall, Rails inspects the database to help build the models it will use. Doing so every time could easily add a lot of overhead and thus cause a slow down. Anyway, without getting too specific(for I know not what I speak, err type), Rails is really slow when run under CGI. To speed things up we need FastCGI!

In a production environment, most Rails applications are being run under a thing called FastCGI. The main benefit of running Rails under FastCGI is speed. FastCGI will load and hold your app in memory so that it doesn’t have to build the entire environment per request. The negatives of FastCGI include extra CPU and RAM usage. On a box that might be shared between a hundred or so accounts it’s not hard to imagine how this might cause some problems.
Thus Rails on shared-boxes sounds bleak, but there are companies out there advertising such services. Now, most hosts on that page mention monthly fees so low it’s scary to think about how bad the service might be. For those not interested in playing web host roulette, let’s talk a little about the most popular of the shared-hosting + Rails setups, TextDrive.


I hope this info was helpfull to you all.. :)

No comments: