PHP Code Generator (Part 1)

Last year I was up in Boston at the SD Best Practices Conference and Expo. One of the vendors was MetaCase. They have a suite of tools that allow you use UML tools to model your logic and then generate it’s code. Apparently the tool has a scripting language that allows you to easily create the code templates that it then uses to generate your final code, and in whatever language you want to generate code for. After being thoroughly sold on the idea I asked what the price was and my hopes drifted away….rapidly. I work for a small company and we simply can’t afford it.

Not all generators are equal

Let’s be specific about what a generator does or can do. There are many generators out there already for PHP. There are DAO generators that abstract database access. There are “full” generators that not only do the dirty database work, but also generate most, if not everything from DAO and all the way to your user interface.

What I ended up with is a slighlty smarter DAO generator. It’s a slight thought shift, but I don’t think of them as DAO’s. They are classes/objects that represent concepts in my model. And, that is what I’m going to explain how I built. I’ll talk about the goals of the generator and the code it generates a little later.

Why generate your code?

I spent several months stewing on the idea that I could write a code generator with some of the qualities that I saw in MetaCase. But, as with any company environment, I had to sell my superiors on the idea. Why should we expend an indefinite amount resources to create a tool that could be at best called experimental? I had to started looking around for ammo. The best thing I could find was a book by Jack Herrington called “Code Generation in Action”. Although it didn’t tell me exactly how to write my generator, it did cover many of the concepts, and most importantly, how to sell upper-management on the many benefits of a code generator.

It can and will save you time in the long run. Consider how much repetitive coding you or your coworkers do on a daily, weekly, or monthly basis. How much time do you spend coding the simple stuff before you can start coding the specific logic that’s going to make your software stand up on all four legs and do something useful?

Code generators save you time by eliminating highly repetitive and monotonous work. And, because the code generator uses the same logic to build code each and every time, you end up with less bugs. How often do you have to go back and fix silly bugs in code that you’ve basically coded tens or hundreds of times before? But, this one time you hadn’t had enough coffee or someone distracted you while you were coding with the latest version of some gizmo.

How many times do you have to go back and change lots of the same code scattered around in the software? What if you could just tweak your code generator configs and regenerate 75% or more of you code in a couple minutes?

Goals

Like a good little programmer I started at the beginning…the requirements and planning. There were some very specific goals for this generator that I already had in mind.

  • Classes should be built dynamically
  • Needed an easy way to describe my objects and how they relate to each other
  • It should also generate SQL statements to create the related tables
  • The generated classes should be easy to extend and override in case we want to customize

Theory behind the generator…

Actually, before I decided to make a big project out of writing this generator, I had already written some simple ones. Basically, they were big templates of a whole class with variables scattered around in the choice places. But, what if you don’t know how the whole class should look. What if the class should be different depending upon the object it should represent or it’s relationship to other objects?

I decided to treat each class as an object. In other words, when the generator sees that it needs to make a new class, it instantiates a new object to represent that class. Now that the generator has an object that represents a specific class and it’s characteristics, it can start adding attributes and methods to it. The same idea holds true for methods. Each possible method in the generator is also represented by an object.

Just to be more clear, I’ll try to represent the idea in PHP code:

$new_class_name = ‘account’;

$obj = new Class_Controller($new_class_name);

$obj->addAttribute(’Name’, ‘text’, 50);
$obj->addMethod(new Validate_Text($this, $params));
$obj->addMethod(new Get_All_Method($this, $params));

$class_code = $obj->generate();

Please don’t get hung up on this example. This is not everything. Nor is it the actual code in the generator. But, it is enough to explain when I say that a class and a method can be represented as an object.

Next time…

I’m going to stop right there for now. I’ve covered why generators are worth the initial effort. And, I’ve started explaining how to generate classes dynamically. I’ll pickup with more of the solutions to my requirements and the mechanics behind them next time. But, what I’ve explained here so far is the crux of what make my generator go.

I know I’m going to get questions about releasing the code. And, honestly, I probably will. It works very well, for us. It’s also a little messy right now, and I need to remove some of the intellectual property specific to my employer. But, I have my employer’s blessing.

Leave a Comment

You must be logged in to post a comment.

Trackback this post  |  Subscribe to the comments via RSS Feed