Leanpub Sample Files With Symfony and Aura

One of the things that bothers me about some cli/console packages is how the commands you write with them end up being tightly coupled to the “framework” the package provides. You extend a command controller, which itself may use service location, and it has to be dispatched to via a specific console mechanism. Your actual command (the business logic) ends up tightly coupled not just to a tool for a specific task but to the package as a whole.

Most of the time I don’t need a “full console application” — I just need to read some input for the command, run my actual command logic, and send some output from the command. The Leanpub Sampler from Matthias Noback is an example of the kind of thing I usually end up doing in small or one-off projects.

Look at the invocation file for the command to generate Leanpub and see how Matthias gets this command running: load the autoloader, create Aura.Cli context and stdio objects, define the getopt flags, and then (this is the key) pass the option values to his real command object.

The command is completely separated from the environment, and fully decoupled from the “framework” that launched the command. The command itself uses the Symfony Finder component and a series of custom iterators. The work performed by the command could run as part of a web process if we wanted. This is a very nice piece of work.

Now, if you want a full console application to combine together a bunch of stuff, that’s cool. Aura has Aura.Cli_Project for that, and there are other things out there for that as well. But the central point remains this: we should strive to keep the actual work of the command separated from the framework of the project as a whole.

Afterword

One of the troubles we have with legacy code is that there’s very little separation of concerns. Setup work, business logic, and presentation logic are all intertwined and difficult to work with separately. As one result of that they are difficult to test.

But it doesn’t have to be that way. My newest book, Modernizing Legacy Applications in PHP, gives you step-by-step instructions on how to get your legacy code under control by eliminating globals and separating concerns. Each chapter shows you exactly one task and how to accomplish it, along with common questions related to that task. When you complete that chapter, you will have improved the quality of your application, and it will keep running until you decide to start the next chapter.

Read more about the book or sign up for notifications on the mailing list below!

[mc4wp_form id=”5830″]

Aura.Marshal, A Database-less non-ORM

Just a quick-hit today regarding Aura while I work on the Modernizing Legacy Applications in PHP book:

It’s probably not correct to call Aura.Marshal an object-relational manager. With ORMs proper like Doctrine and Propel, the ORM issues queries for you using an embedded or preferred database library.

With Aura.Marshal, you use the data retrieval tools of your choice and write your own queries to retrieve data from a data source. You then load the result data into an entity type object, and the marshal automatically wires up entity and collection objects for you based on a relationship scheme you define for it.

The great benefit of this approach is that it completely decouples the in-memory object wiring from the act of doing the queries in the first place. The Marshal knows how to build and interrelate the objects, but it has no idea how to get the data for those objects in the first place.

Via Aura.Marshal, A Database-less non-ORM.

What Application Layer Does A DI Container Belong In?

James fuller asks:

any thoughts about which layer of the application we should be using a DI container like Aura.Di? Highest layer possible?

Twitter is too constrained and ephemeral for a good response, so I’ll answer that question here.

First, we need to remember that a Dependency Injection container and a Service Locator are indistinguishable from an implementation perspective. (This is a view I accepted only recently.) The difference is in their use: if a container is ever placed into an object so the object can retrieve its own dependencies, that container is being used as a Service Locator. Conversely, if the container stays entirely outside an object so that dependencies are pushed into the object, the container is being used for dependency injection.

If we accept that description, the proper layer for a DI container is outside every other layer in the application (with the possible exception of Factory classes). That means the DI container is part of the bootstrapping code that sets up the application, and not part of anything else.

As an example, we can imagine a web application bootstrap script that looks like this:

<?php
// set up the autoloader
include '/path/to/autoload.php';

// create and set up a Container
$container = new Container;
$container->load('/path/to/container_config.php');

// retrieve a front controller service and run it
$front_controller = $container->get('front_controller');
$front_controller->exec();
?>

The purpose of the bootstrap is to create and configure the container with all its services and settings, then pull one object out of the container and invoke it. None of the objects in the system has to know that the container even exists. All of the objects are being created via the container, so in a way the container “contains” the entire object graph.

The part I had the hardest time getting about real dependency injection was this: If you have a class 2 or 3 layers down in the application, and that class needs dependencies, how do they get injected? Don’t you have to pass the dependencies through the intervening layers, and then doesn’t that break a lot of rules, along with violating plain common sense? And what if that class needs access to several different but related objects, but doesn’t necessarily know what they are in advance?

The key for me was realizing that all object creation work happens in the container and not in the classes themselves. This is an alien way of looking at things for most PHP developers, who are more used to Singleton, Registry, and Service Locator, not to mention static calls to ActiveRecord objects. All of these patterns of usage mess with separation of dependencies, but are very common in PHP land, and form the basis of most PHP developers’ understanding of how to work with dependencies.

It took me a year to really “get” the concept of dependency injection, under tutelage from guys like Jeff Moore and Marcus Baker, along with the writings of Misko Hevery. Once I understood it, I wrote the Aura.Di readme file as an introductory document to step readers through the various stages of dependency allocation. Perhaps that document will be helpful to others, even if they don’t choose Aura.Di as a container.

Afterword

If you work with a legacy application, you already know how hard it is to track dependencies throughout the code. Sometimes the dependencies are global, sometimes they are created inside that class that needs them, and sometimes there is a service locator implementation floating around inside the classes. This makes it frustrating to track down bugs and make wide-ranging changes, and terribly difficult to write tests because everything depends on everything else.

But it doesn’t have to stay that way. My new book, Modernizing Legacy Applications in PHP, gives detailed instructions that will lead you step-by-step from an include-oriented mess of page scripts to a modern architecture using dependency injection techniques.

You can buy the book in early-access mode today, or sign up on the mailing list below to get more information as it becomes available!

[mc4wp_form id=”5830″]

“Page Script” As A Degenerate Controller

I read a good conversation on Reddit last week titled Thoughts on MVC vs. Pages for Everything?. Short version: the OP asks about the advantges of using a formalized model-view-controller system vs a series of typical PHP page scripts. The entire discussion is worth reading.

As the author of a book on modernizing legacy applications in PHP, this is a topic I am very familiar with. Almost all of the legacy applications I’ve had to deal with were page-based. In doing the work to modernize them, there comes a time where the page script has been refactored to look very much like a page controller, with some distinct but not critical differences. As such, I have come to consider the typical PHP page script to be a degenerate form of a page controller. With a little imagination, I think it’s easy to see why.

First, recall the basic operational cycle of almost every PHP framework ever, including the micro-frameworks:

  • a bootstrap index.php file that does some setup work, which hands off to …

  • a front-controller (typically a router/dispatch system) which picks …

  • a page controller or action method that calls services and collates the results into a data structure, which is passed to …

  • a view layer that renders the results for the client.

(In an earlier version of this dispatch cycle I split “page controller” and “action method” into two separate steps, and in many cases they may still be two separate steps.)

When we look at this cycle, it’s not so hard to envision a plain PHP script doing the same things. The web server itself becomes a simplified front controller+router+dispatcher, picking the “controller” (page script) to run based on the URL path mapped to the file system. After that the work is exactly the same, albeit combined into a single blob of code.

Even then, the page script can keep itself in good order by using service objects instead of embedding all the logic in one place. It should be easy to imagine converting a page script that combines the setup, data retrieval, data manipulation, and data output concerns as a blob of intermingled code, into something more like the following, where the concerns are in blocks:

<?php
// config, global vars, autoloader, etc
require_once '../setup.php';

// dependencies
$request = new Request($GLOBALS);
$response = new Response($GLOBALS);
$db = new Database($user, $pass, $host);
$service = new Service($db);
$view = new View;

// data retrieval
$page_number = (int) $request->get('page', 1);
$records = $service->fetchPage($page_number);

// data rendering
$view->setTemplate('/path/to/template.php');
$view->assign('records', $records);
$content = $view->render();

// send back to client
$response->setContent($content);
$response->send();
?>

That page script is not wildly different from what goes on inside a formal MVC framework. Yes, there are still some legacy elements. These include the global require setup at the top, the use of query parameters instead of path-info parameters, and the lack of a formal DI container (although for scripts like this a container proper might be overkill at the start).

On the other hand, most of the work is being done in classes and objects, not embeddded directly in the page script itself, just as you would see in a formal controller class method. These support classes and objects are independently testable; only the page script “controller” itself is not. But be honest here: of all the formal controller methods you have seen in the wild, how many were independently testable? My guess is “not many.”

Once we have refactored a page script to something like the above form, it becomes a lot easier to see how we might convert this degenerate controller over to a formal MVC framework with even further separation of concerns.

Afterword

Are you overwhelmed by a legacy application full of page scripts, spaghetti includes, and global variables? Do you want to improve the quality of the code, but don’t know where to begin or how to proceeed?

My new book, Modernizing Legacy Applications in PHP, gives step-by-step instructions on how to get your code under control and keep your application running the whole time.

Buy the early access version now and get free updates as it is completed, or sign up on the mailing list below for more information and a free sample chapter.

[mc4wp_form id=”5830″]