Zend_Tool and ZF 1.8
By now, you are sure to have heard the news, Zend Framework 1.8 has landed.
With ZF 1.8 comes several new features such as Zend_Application,
Zend_Navigation, Zend_Tag_Cloud, and, my favorite Zend_Tool. Zend_Tool is
not a component in the typical sense. Most components have a class at its
top level namespace, Zend_Tool does not. Most components are generally
consumed inside your application code to simplify runtime tasks, Zend_Tool
does not. Zend_Tool is more akin to a framework than a component
– a framework within a framework.
So what is Zend_Tool?
The initiative began by exploring what it would take to create a next
generation framework for RAD, or Rapid Application Development. RAD as you
can imagine, is a term with a pretty wide definition. In its most general
sense, its a term that describes the speed at which you can build the resources
that form your application’s backlog of requirements. In the most ideal of
situations, the initial development, or loading phase of a project, should be
kept to an absolute minimum such that the developers can get on with the more
interesting development. After all, the more “interesting development” is more
than likely the reason the application was born.
So if there is interesting development, what is the uninteresting development?
For Zend Framework, and most MVC based frameworks for that matter, it’s the
process of creating the initial project resources common to all projects: the
primary project structure, initial configuration files, initial bootstrapping
and autoloading code, etc. It also includes the tasks of error handling,
controller creation, and view creation to name a few more. For someone just
getting involved with ZF, some of these tasks would require hours of reading
though tutorials, manuals, and quickstarts. Not exactly “rapid”.
Zend_Tool As A Framework
Instead of whipping together a system that was targeted specifically for
creating ZF based applications, specifically on the command line, and strictly
generating code and not modifying existing code, we set out to build a system
extensible in every regard that should concern a developer. Zend_Tool was
designed to facilitate abstraction at all the necessary points where we felt
that developers would want to extend the system. For example, while we have a
primary CLI client, the tooling framework was developed as a generic RPC
(remote procedure call) system to enable developing other non-CLI clients.
While we have the stock providers (the capabilities of the system), the
interfaces to build future providers has remained simple and easy to extend
Zend_CodeGenerator & Zend_Reflection
During development, we discovered a couple of problem areas that had no solid
solution. Code generation is one of those areas. Generally speaking, when
you talk about generating code, it’s typically a template-based approach; the
generated code comes from template files which are usually written without
regard as to whether or not they are well-formed (by the target language’s
standard). Having an templated approach also introduces the risk of developers
going outside the suggested coding standard and generating generally bad code
(bad code in this sense is both code that will not run as well as poorly
formatted code). So, we immediately realized that there was an opportunity to
create a component that would provide an object-oriented interface, similar to
that of PHP’s Reflection API, with the sole purpose of generating well-formed
and well-formatted object oriented code. It should be said that the
Zend_CodeGenerator component can be used without the rest of the
Zend_Tool stack. This means that if you ever find yourself in a position
where you need to repeatedly generate code, the first place you should look
Zend_CodeGenerator doesn’t simply write code from scratch; it has the
capability of reading existing code, modifying it, and producing new
code. This is primarily due to the other component born out of Zend_Tool,
Zend_Reflection. Zend_Reflection is not, and I repeat, not a
reinvention of the wheel. In fact, it extends PHP’s Reflection API to add
support for user-based extensions (i.e., extending the Reflection API),
docblock reflection (and annotation tags within docblocks), and file-based
reflection. The semantics of the component are true to its origins, and
can be used as a drop in replacement when the additional feature-set is needed.
Zend_CodeGenerator and Zend_Reflection have similar API’s, with Zend_Reflection
targetting reading code structure, and Zend_CodeGenerator targetting writing
code structure. Together these two components make it easy to reflect and
write code during the development process of an application.
Zend_Tool Command Line Client et. al.
It goes without saying that CLI based RAD is a very highly desired for ZF
developers. As mentioned previously, the task of setting up the initial
resources of a project can be tedious. Many developers prefer to interact with
their development environment through the terminal, or command line, so
naturally, this is the place we decided would make the most sense to build a
client into Zend_Tool. This does not mean it will be the only client; as
mentioned previously, the client functionality of Zend_Tool has been abstracted
in such a way that additional clients can be built to interact with Zend_Tool.
IDEs and text editors have an opportunity to hook into the client framework and
dispatch commands from their native interface. Two potential extension points
include to of my favorite tools, Zend Studio and Textmate — but the
possibilities are almost limitless. Any client that can execute PHP can
effectively build on top of Zend_Tool for tooling needs.
Since project development is an iterative process, the tooling side of the
equation also needs to keep track of history, so to speak. What we mean by
history is keeping track of the actions you have performed: what have you
created, where is it located in the project structure, and what is its context
in the project? As an example, after creating a project, you might want to
create a controller. For all intents and purposes, a controller is simply a file
with a class in it; how can the tooling environment know the difference between
a regular file and a controller file?
Zend_Tool_Project sets out to solve this problem. Zend_Tool_Project is the
bundle of functionality built to work with Zend_Tool_Framework to deliver a
solution to the project management problem. Zend_Tool_Project keeps track of
the resources inside your application, where they are in relation to each other,
and the name by which you refer to them; this is the key to allowing “iterative
development”. As an example, if you had created that project, with a controller
named “foo”; you might want to add actions to that controller later on down the
line. To make development as seamless as possible, it should be as simple to
modify as it was to create resources. To do this, Zend_Tool_Project keeps track
of everything you’ve done inside your project.
In addition to being an application resource tracker, Zend_Tool_Project is the
key part of Zend_Tool that delivers the “build a Zend Framework based project”
solution. Zend_Tool_Project knows specifically what a project, controller, view,
bootstrap class, index.php file, and so on, should look like, and aids you in
creating them. If you were to take Zend_Tool_Project out of the Zend_Tool
runtime, you’d be left with just the framework or platform to build a tooling
system with. That said, any project can use Zend_Tool_Framework to build tools
fulfilling their needs.
What It Can Currently Do
So, with all that in mind. What can it do right now? Instead of talking about
it, lets walk through a few screenshots.
In addition to what it can already do in the 1.8 release, several additional
features are already in the pipeline. Some of these features are considered
beta (which is why they are not in the distribution), or are still in the
design phase. For example, with Zend_Application, we are finally deciding
what a “model” should look like, even if we are only talking about what the
name should be. Also, with 1.8 we are finally publishing the default project
structure. For a project that has a very firm footing in the “component
library” space, these are tremendous steps for Zend Framework.
In addition to model support, we also have plans to add “module” support (for
building componentized applications), database connectivity, and Zend_Db_Table
file generation. Look for these feature in the upcoming releases.
Additionally, since Zend_Tool is so extensible, new (more beta) features can
be distributed by outside projects that plug directly into Zend_Tool.