We do what we must, because we can.
Loosely Typed in Ohio

Software Stop Asking Now

I’m vocal about how PHP sucks. I make no bones about it, and try to hasten the company’s move to better languages. Occasionally I’m challenged on this. I submit for your approval the following code:

if (empty(trim($string)))

This will exert a Fatal Error every single time. With a horrible message: “Can’t use function return value in write context.”

WTF?

Sympathizers: I know what you’re about to say. empty() is a language construct that specifically looks at a variable. You just have to assign the trim() result back to a variable first for this to work. If you’d read the manual entry for empty() you’d know that!

Fuck that noise. I don’t care if it’s well documented. I don’t care that technically speaking the empty() construct can only check variables. It does not matter. This is shit behavior.

Sympathizers: grow some balls backbone. PHP sucks. It’s okay to admit it. Yeah, it has some redeeming value, else we wouldn’t be discussing it now. But you’re letting the PHP developers get away with murder here.

PHP Core Developers: Yes, the language you write powers a metric shit-ton of awesome businesses, Innvoa included. That doesn’t give you a free pass to do fucking idiotic things like this. Fix it!

Software Tangible Rails Benefits

We’re nearly to the launch of our first Rails application for our largest client, which means it’s about time for me to write a rah-rah style post about how awesome developing the application was.

First blood, so to speak, goes to a Facebook App Chad wrote in Rails, but this app is more of a classic pattern for Innova: we get some data from a client, import it into Microsoft SQL Server, and clean things up as we go. These things don’t necessarily scream “Rails,” but she was up to the task nonetheless.

Coming from PHP development, there are several things that rocked my house as I was developing this app, things that our old Zend Framework or PHP simply couldn’t do:

  • script/console Being able to spawn an interactive session inside your application’s environment is ridiculously helpful. I had the basic application logic finished the first day because I was able to fire up a console and run some quick ActiveRecord commands to see what worked. And if something broke, I was able to fire up a console and start firing off commands and inspecting results. Much quicker than the var_dump then die style of PHP development we were using.

  • Plugins, esp. will_paginate Rails plugins are drop-in chunks of code that give you functionality you didn’t have before. In my case, I needed to paginate a set of database rows, which isn’t the most fun task. After I installed will_paginate, the work was done. I had an easy way to get paginated results from my models, and a one-step way to generate the page selection HTML. A lot of people cry about Ruby’s open classes, but things like this wouldn’t be possible otherwise.

  • Routes In PHP, we had to write several library functions to generate URLs for our site, for use in HTML links. Rails’ built in named routes and link\_to helper meant I never had to write any kind of setup code beyond the initial route.

That last one might seem like I’m really scraping the bottom of the barrel, but that’s just one example of a pattern I’ve noticed in Rails. link_to_unless_current is another: \writing a function that either generates a link or some non-link text based on what page you’re on isn’t hard, but since almost every web application does this you don’t have to write it. The number of times I’ve said something like “Crap, Rails has a built-in feature that handles that” or “oh, I just need this plugin, it takes care of it” is really astonishing.

Software Zend Framework: WTF?

As I was trying out Zend Framework 1.6.2, certain things made me cringe:

  • There’s a “Minimal” distribution, but it’s just as large as ever. Non-minimal I guess means with Dojo and unit tests. Forget the fact that I might never use Zend_Search_Lucene (Lucene search provider), Zend_Gdata (Googel Data API), or Zend_Service_Nirvanix (no clue).
  • The “QuickStart” is ten-pages long and is a full-on tutorial on how to build a basic application. Not the “download this, put these files here, go to town” I was hoping for. Perhaps I’m being pedantic, forge on.
  • On page 5, you create a bootstrap.php file which contains a bunch of application configuration details. All of these are pretty much stock and won’t change between applications. On page 7, you add a bunch of stuff to the bootstrap file so your application can do something esoteric like use view layouts. Also, there’s no explicit point telling you where to add the stuff. Hint: take the last “cleanup” step, remove that, and add in all the new code. This happens every time you modify the bootstrap. Yes, we do this more than once.
  • When you’re creating your first layout, there’s nothing that tells you what file to put the example layout code in. I had to google that, find an unrelated tutorial, and guess-and-check my way back to a working sample app. (The unrelated Zend 1.5 tutorial said to use “default.phtml”, you need to use “layout.phtml” in whatever directory is in the bootstrap file.)
  • On page 8 you update the bootstrap again, so your app has the privilege of reading a database config file.
  • Whoops. On page 9 you update the bootstrap for the last time (in this tutorial). Because before when you set it up to read the database config file you didn’t set it up to actually connect to a database.
  • Apparently, in the controllers you’re creating (on page 9), you have to tell the controller to fetch the controller’s model explicitly. Also your model has-a Zend_Db_Table object, but not just any Zend_DB_Table object – you create a subclass! So: Your “table model” explicitly gives the table name, and overrides the normal insert() and update() methods. Then you have a regular application Model that has this “table model” as an instance variable. In this “regular Application Model”, you have to explicitly write a save() function that takes a hash, rejects all of the entires whose keys don’t match a table column name, and then insert the array. You also write a fetchEntries() function that is just a wrapper around the much longer $this-getTable()-fetchAll(’1′)-toArray(); call. Finally, you write a fetchEntry method that fetches an entry by ID. By far one of the most horrifying things I read, and this is the actual point where I gave up.
  • Just for kicks, I checked out page 10 that shows you how to create a form the Zend Framework way. I was glad I stopped at the previous step: you actually define a subclass of Zend_Form that defines your form programmatically as an object, and your view automatically wires up based on the class name! So the only thing in your view is ?= $this-form. Not, y’know, HTML or anything. (Astute readers here will wonder, if we’re generating forms this way, how are they styled? Why, you just override the form’s decorator object! It is to gag.)

So, it turns out that steps 1-4 were pretty much things that a shell script could do for me.

After that I find myself writing code to do things like have my models save an array of data properly, or explicitly telling my “GuestbookController” that it should go out, require_once the “Guestbook” model (their autoloader only handles “library” items. “Application” items like models still need to be explicitly required!), and then instantiate a new Model_Guestbook().

And each time dorking with my bootstrap.php file and telling it to do things that the framework should really know how to do on its own.

And the form class!

Dear goodness, this is the way people choose do to things?

Software Database Models I Have Known And Endured

One thing you might have noticed that we do is SQL. We do a lot of SQL, so you’d think we would have figured out the best way of hooking up applications to databases.

To an extent, we have become so familiar with the requirements of database-driven development that we have come to accept the tools that we have as being adequate. Even ODBC.

Obviously we’ve long ago moved past PHP functions like mysql_fetch_row. We expect things like sanitizing and escaping, multiple vendor support, query abstraction, and so on. We look back fondly on the clumsy simplicity (and scope for injection) of things like this:

    PHP

    mysql_query( "SELECT * FROM T_Shirt WHERE color = '{$favorite_color}'" );

Nowadays we’re more likely to fetch records through a framework API, such as this use of Zend Framework’s Zend_Db:

    PHP / Zend Framework

    $db = Page::getDb();
    $select = $db->select();
    $select->from( 'T_Shirts' );
    $select->where( 'color = ?', $favorite_color );
    
    return $db->fetchAll( $select );

Because the query is broken down into a set of calls we can pass the select object around before we do the fetch. This is surprisingly handy.

But what else is out there that might be better than what we’re doing now? What would be the next step, the thing that would make Zend_Db look like mysql_query?

Continue Reading…

Software Eclipse FTW!

Eclipse: when it rocks it rocks, but when it goes pear-shaped, it really does go pear-shaped.

Close
E-mail It
Socialized through Gregarious 42