Paul M. Jones

Don't listen to the crowd, they say "jump."

Aura Version 2 Beta Releases: Includer, Autoload, Sql, Dispatcher

In addition to the Aura.Autoload v2 “Google Beta” release from last week, we have been releasing v2 beta versions of other packages as well:

Hey, that looks like a pattern: one release per weekday of the new year. Who knows what tomorrow will bring? Regardless, you can see continuing updates on our v2 packages page.

Via Version 2 Beta Releases | Includer, Autoload, Sql, Dispatcher.


First PSR-4 Autoloader Released: Aura.Autoload 2.0.0-beta1

I suppose it makes sense that since the the main author behind the PSR-4 Autoloader recommendation is also the lead on the Aura project, that Aura would have the first PSR-4 implementation. You can download it here

and you can find the README here (or in the download, of course):

I expect Composer will have support for PSR-4 soon as well.

Via http://auraphp.com/blog/2014/01/03/first-psr-4-autoloader/.


Passing the Benchmarking Torch After 7 Years

Long-time readers will recall that I am interested in performance benchmarks as a tool to help discover the outer limits of framework responsiveness. See the blog category along with the most recent measurement report and the GitHub repo for replicating the results on your own.

Benchmarking is useful because it helps you decide if it makes more sense to work on improving your application, improving your framework, or improving your server. If the maximum dynamic responsiveness of the framework in question is 200 req/sec, and you need 300 req/sec, then there is no code you can add in your application to make it go faster in a dynamic scenario; you will have to look at the framework or the server. (Lazy reader who considers himself an unappreciated genius interjects: “But you can cache it!” I said a dynamic scenario, not a static one.)

There’s a lot of emotion and drama associated with benchmarking. The subjects that come in “first place” too often point to it as SCIENCE PROVES WE ARE BEST and the subjects that come in “last place” respond with variations of THIS IS STUPID AND PROVES NOTHING. (That is, until the last-placers run their own benchmarks where they come in first, and suddenly it’s a great marketing point. I’m looking at you, Symfony.) The point in benchmarking is to add information to your decision-making process so you can make better use of your limited resources of time and effort, and choose between competing tradeoffs in a more informed way. Speed alone over-and-above anything and everything is for suckers; it’s an important point, not the important point, when evaluating tradeoffs.

Leaving the elements of drama aside, benchmarking properly is difficult and time-consuming work. For my own limited benchmarks, it took three days or more to properly update, test, run, fix, and re-run to perform them well, even with automated scripts to do the setup and analysis. And that was for the most basic bare bones “hello world” that benchmarks only the dynamic dispatch cycle (bootstrap, front controller, page controller, action method, and view rendering).

Enter the guys at TechEmpower.

They’re doing a series of regular benchmarks that includes not just a double-handful of PHP frameworks, but 90 frameworks/languages/foundations across several languages. They do the basic “hello world” bench in addition to a few others, such as ORM/database speed. They appear to share an approach similar to the one I first published in Nov 2006 and improved with the help of Clay Loveless in Jan 2007. The TechEmpower motivations appear to the be similar to mine as well. They have equalled and then exceeded the efforts that I’ve been able to put forth on my own. From what I can tell it’s really good work.

With that, I am happy to say that I will be retiring my benchmarking project in favor of the TechEmpower one. Until futher notice, I’ll be combining my efforts (such as they may be) with the TechEmpower folks.



Which is Lighter, Silex or Aura.Web_Project?

Always remember that there is no such thing as “bloated” or “heavy” or “light”; there is only “heavier” or “lighter” or “more bloated” or “less bloated” in comparison to something else.

… let’s go with that article [on Silex] and use its approach to make a comparison between Silex and Aura.Web_Project to see if my earlier claim, using the terms and measurements outlined by the Silex post author, is accurate.

  • If you measure by the number of package dependencies, disregarding how similar functionality is split up between packages, then Silex is lighter.

  • If you measure by the total disk usage, Aura.Web_Project is lighter.

  • If you measure by the total NCLOC, Aura.Web_Project is lighter.

  • If you measure by the total class count, Aura.Web_Project is lighter.

  • If you measure by the acutual-usage class count, disregarding how similar functionality is split up among classes, then Silex is lighter.

  • If you measure by the actual-usage NCLOC, Aura.Web_Project is lighter.

  • If you measure by how many classes “for the most part” are in the public API, Aura.Web_Project is lighter.

In 5 of the 7 measures put forth by the original Silex article, Aura.Web_Project is the lighter of the two.

UPDATE: Via Which is Lighter, Silex or Aura.Web_Project?


Quicker, Easier, More Seductive: Names, Usage, and Intent

Yesterday’s post in this unexpected series on Dependency Injection vs Service Locator generated a lot of excellent and productive feedback in Twitter, on the PHP-FIG mailing list, and in the comments.

In that post, I opined that there was a significant difference between how Service Locator containers and Dependency Injection containers are implemented. This came from my sense that because they have different names they must be different things, and so I had been trying to find a way to discern the difference by looking at the implementations.

They’re Different Names For The Same Thing …

As the disucussion progressed, it became more clear to me that there really is no significant difference in how Dependency Injection containers and Service Locator containers are written. They are both Inversion of Control (IOC) containers, and are not distinguishable by their code, API, features, etc. (although some may have more or fewer features than others).

As such, the terms Dependency Injection and Service Locator appear to be interchangeable in the sense that a container is a container is a container. The difference in naming comes from how the container is used, not how the container is implemented:

  • When the container is used outside a non-Factory object, you are using the container for Depedency Injection.

  • When the container is used inside a non-Factory object, you are using the container as a Service Locator.

(Side note: Using the container inside a Factory object does not seem to be a case of either Dependency Injection or Service Locator specifically; it’s just a generic container usage at that point. This stems from the idea that object creation should be separated from every other type of object operation; that is, a class should either create an object, or it should operate on objects, not both. Factory, Builder, etc. classes are thereforce special cases.)

… But The Names Still Indicate A Difference

This still leaves me with a trio of related issues: usage, naming, and intent.

I am big on trying to use the right names for things. I think it’s important for clear, consistent communcation that when Developer A uses a word or phrase to describe something, Developer B should be able to understand what Developer A is getting at. The need for common understanding should be so obvious as to not require pointing out. With that in mind …

  • If an author creates a “Dependency Injection” container but his intent is for it to be injected into non-Factory objects so the objects can retrieve their dependencies, he has named it incorrectly. He can correctly call it a “Container” or “IocContainer” in general, or a “Locator” or “Service Locator” in specific, but his intent and usage are clearly at odds with his naming. (Closures and functions count here, too. Injecting a “Dependency Injection” container into a closure or function is a Service Locator usage of that container.)

  • Similarly, if a user uses something labeled as a “Dependency Injection” container by injecting it into his non-Factory objects so they can retrieve their dependencies, his use is at odds with the naming and intent of the container. He is using it as a Service Locator.

  • Conversely, if an author creates a “Service Locator” that is used only in Factory objects, and never in other kinds of objects, the name is at odds with the intent and usage as well. That’s a “Dependency Injection” container, or more generically a “Container” or “IocContainer”.

  • Finally, if a user uses something labeled as a “Service Locator” and never injects it into his non-Factory objects, his use is at odds with the naming and intent of the container. He’s using it for Dependency Injection.

Conclusion

As a result of all this, I am left with the conclusion that container authors should be very careful about their naming, and that container users should be disciplined about their usage, both based on the intent indicated by the container’s name:

  • If the author intends the container to be injected into non-Factory objects, including closures and functions, call it “Locator” or “Service Locator”. Users should honor that intent.

  • If the intent is that the container never be injected into non-Factory objects, including closures and functions, call it “DI” or “Dependency Injection”. Users should honor that intent.

  • If the author has mixed intent, call it a generic “Container” or “IocContainer”. Users can mix Dependency Injection and Service Locator in Factory and non-Factory objects and closures.

Again, the point here is to make sure that other people know what we’re talking about when we use these terms. Using the wrong names leads to confusion regarding usage and intent.

Afterword

Are you overwhelmed by a legacy PHP codebase? Do you want to improve it, but don’t know where to start? My book, Modernizing Legacy Applications in PHP, will lead you step-by-step through a series of small, incremental changes that will dramatically improve the quality of your legacy codebase.



Quicker, Easier, More Seductive: How To Tell A DI Container From A Service Locator

(In this unexpected series, we’ve been talking about the use of Service Locator versus Dependency Injection.)

UPDATE: Please see the next post in this series for important corrections and updates regarding the essay below.


It is easy to confuse a Dependency Injection container with a Service Locator. They are very similar to each other. The differences are subtle. Indeed, it’s even possible to use a Dependency Injection container as a Service Locator, although I think it’s difficult to use a Service Locator as a Dependency Injection container. They are both sub-patterns of a more generic pattern called Inversion of Contol, and some people confuse the term Dependency Injection with the more generic term Inversion of Control.

How To Tell The Difference

I’ve been thinking about what heuristic or rule-of-thumb one could use to easily tell which is which. So far I’ve been leaning in the direction of: “Can you create new instances without defining a service?” If you can, it’s a Dependency Injection container; otherwise, it’s a Service Locator. There are several variations on that prhasing:

  • If you can create a new instance of a class without having to define a service, it’s a Dependency Injection container.

  • If you have to define a service in order to get an object out of the container, it’s a Service Locator.

  • If you cannot create a new instance of a class without defining it as a service, it’s a Service Locator.

By this I mean that you should be able to repeatedly create new, discrete, independent instances of a class, without having to define it as a service in the container.

Examples

Given the above heuristic, here’s an example of Dependency Injection using Aura.Di:

// they are separate instances, not shared services
$foo_1 = $di->newInstance('FooBarBaz');
$foo_2 = $di->newInstance('FooBarBaz');
var_dump($foo_1 === $foo_2); // false

Might you need to set up constructor parameters, setters, etc. for the newInstance() calls? Sure; Aura.Di allows for inherited and overridable constructor parameters and setter methods:

// given __construct($gir)
$di->params['FooBarBaz']['gir'] = $di->newInstance('DibZimGir');

// given a setter method setOperation($operation_name)
$di->setter['FooBarBaz']['setOperation'] = 'ImpendingDoom';

The main point is that whenever the Dependency Injection container creates a class, it can do so without having to define that class as a reusable service.

In contrast, a Service Locator requires that you define a service, and then you can retrieve a shared instance of that service from the container. Here’s an example with my trivial Service Locator example from earlier in this series:

// define shared services
$locator->set('gir', function () use ($locator) {
    return new DibZimGir;
}

$locator->set('foo', function () use ($locator) {
    $foo = new FooBarBaz($locator->get('gir'));
    $foo->setOperation('ImpendingDoom');
    return $foo;
});

// these are shared services, not separate instances
$foo_1 = $locator->get('foo');
$foo_2 = $locator->get('foo');
var_dump($foo_1 === $foo_2); // true

Who’s Doing What?

I had a quick look at some containers in PHP land to see how well they fulfill the above heuristic; my assessment is as follows:

Some notes:

  1. Laravel: The documentation calls the container an “IoC” (Inversion of Control) container but mentions “Dependency Injection” throughout, never “Service Locator.” It is clear from the container’s usage throughout the rest of the codebase that it is in fact a Service Locator, since the container itself is injected into the classes that need services. This strikes me something that can be remedied with a documenation change, since the class itself is named in a generic way. UPDATE: the project lead has informed me of the public make() method on the container that creates new instances. Although I pick nits over the naming (using $class and newInstance() instead of $abstract and make() would make things more obvious IMO) it does fulfill the above heuristic.

  2. Pimple: Interestingly, Pimple has a factory() method that will return independent instance of a service. Some may think of this as meeting the heuristic above, but I don’t think it does; you still have to define the service, after all. I suppose one might define the service as a factory for a particular class name, and name the service for the class to be factoried, but that’s not quite the same; among other things, you still have to define a service for each class you want to factory.

  3. Slim: This uses $app as a Service Locator. To his credit, Josh Lockhart does not call it either a Service Locator or a Dependency Injection container, so kudos to @codeguy for avoiding the issue altogether.

  4. Symfony DependencyInjection component: My quick review of the codebase did not reveal a way to create a new instance of a class. Instead of a missing capability, It seems more likely to me that I just did not see it. If there are any Symfony guys reading this, please let me know how to create a new instance of a class with the Symfony DependencyInjection component, and I’ll update the description.

Conclusion

According to the heuristic above, some of the things calling themselves Dependency Injection systems are probably better described as Service Locators. They might be Containers (or Inversion of Control containers) in a generic sense, but they are not Dependency Injection containers. There’s nothing wrong with not-being a DI container, but using the wrong names for things leads to confusion on a topic filled with subtleties.

Of course, I’m sure that the folks using these Service Locator systems will have plently of rationalizations for why (1) the preferred system of their particular tribe really is a Dependency Injection container no matter what made-up rules Paul wants to apply, and (2) the distinction doesn’t really matter anyway, why even bring it up, just use their preferred system. I look forward to the comments on this one. ;-)

Afterword

Are you overwhelmed by a legacy PHP codebase? Do you want to improve it, but don’t know where to start? My book, Modernizing Legacy Applications in PHP, will lead you step-by-step through a series of small, incremental changes that will dramatically improve the quality of your legacy codebase.



The "80/20" Rule Leads To The 1%

The 80/20 rules, formally known as the Pareto Principle, is a common rule-of-thumb in lots of situations. In general, it says that 80% of all effects in a particular situation comes from only 20% of the causes in that same situation. If you can eliminate the right 20% of the problem causes, then you can get rid of 80% of the effects from those problems.

Reading Taleb's "Antifragile", he points out that the complaint against "the one percent" holding 50% of the wealth in the country is a natural outgrowth of the 80/20 rule. There's no conspiracy, it just works out that way. Of the top 20%, 20% of them will hold 80% of that wealth; of that subgroup, another 20% will hold 80% of that wealth, and so on. Eventually we find that about 0.8% of a population will hold about 51.2% of the wealth, just as a rule-of-thumb. So, a baseline point of 1% of the population holding half the resources doesn't seem that out of line to me, mathematically and statistically speaking.


Lighter than Silex, and Slimmer than Slim: Aura.Web_Project, the Micro/Macro Framework

... the Aura.Web_Project package is a minimalist web-specific project framework that starts out small and grows only as you need it.

By “minimal” we mean very minimal. The project package provides only a dependency injection container, a configuration system, a router, a dispatcher, a pair of request and response objects, and a Monolog instance for logging.

This minimal implementation should not be taken as “restrictive”:

  • The DI container, coupled with the project kernel’s two-stage configuration, allows a wide range of programmatic service definitions. This means no more static calls to configure services; edit the modify stage config files, pull a service out of the container, and operate on it directly.

  • You can add any library you want into the project, not just Aura libraries, through Composer and the DI container. This means the bundle/plugin universe is made up of anything written in PHP, not just Aura-specific plugins.

  • As noted in earlier articles in this series, the router and dispatcher are completely separated from each other, and are built with iterative refactoring in mind. This means you can start with micro-framework-like closure controllers, and work your way into more complex controller objects of your own design.


Book Announcement: Modernizing Legacy Applications in PHP

There you are, working late for the second night this week. Everyone else in the office has gone home. Most of the lights are out. Yesterday it was trying to copy a feature over to a different section of the site, because marketing wanted their new client to see it there. Today, you have just finished tracking down a globals-related bug in an SQL query embedded in a page script. It revealed itself only after yesterday’s feature addition. You had to search across scores of PHP files to find it. You commit the change, push it to the common repository, and update the bug report so that QA can check on it.

Although you are relieved, you are still frustrated and worried. Who knows what break this fix will reveal? The work should not be this hard.

Your Legacy Application

You were so excited when you got the job. The interviews went well. You clearly knew more than almost everyone else there. The other developers seemed like they really needed your help and expertise. The managers gave you a new laptop and a new LCD screen so you could be as efficient as possible. It was the perfect setup. You were eager to get to work showing off your skills and abilities to make the application sing, and get the project back on schedule.

But then you checked out the code base. It was a mess. It had been architected over several years by mulitple different lead developers, and it showed. There was no consistent pattern to any of the structure. The oldest core of the system was a collection of “include” files that ran several levels deep. Later, someone had bolted on some class-oriented libraries, and third person has decided to try a framework rewrite. All of it was done in a different coding styles, with different naming conventions. The codebase is a mixed-up aggregagation of PHP, HTML, SQL, JS, and CSS, frequently all in the same file. And there are no tests at all! The “tests” are the QA team running over the site once or twice a week.

After that first day, when you felt so enthusiastic, you have been reduced to feeling like a brand-new beginner every day since. It’s humiliating. Each day has been a new frustration, a new “WTF?” moment replayed in a dozen different ways. You want very much to to improve the codebase as it is, so that you can impose some sense and reason onto it, but the code is such an overwhelming mess of spaghetti that you don’t even know where to start.

Overwhelmed and drowning in bad code that you inherited from others, you’re ready to give up.

Modernize Your Legacy Application

But what if I told you it didn’t have to be this way? What if I told you there was a specific series of small, incremental changes you could make over time to slowly make the codebase better, more modern, and thereby reduce your own sense that things are futile?

My upcoming book, “Modernizing Legacy Applications in PHP”, does exactly that. Using my talk “It Was Like That When I Got Here” as a starting point, I condense 15 years of fixing PHP codebases into a collection of specific steps to complete in order. As you apply these small fixes, each one building on the last, you will be able to restructure your codebase from a spaghetti mess to a testable, organized, modernized application, free of globals and mixed concerns.

Would you like to have that knowledge, distilled into an easy-to-understand book? Sign up on the mailing list below, and you’ll be the among the first to:

  • Find out how the book is going (and when it’s ready for purchase!)

  • Receive hints on how to improve your codebase now

  • Get a free pre-publication chapter

I promise, you’ll never receive any spam or other unwanted messages on this list. Add your email today!



Splitting The Blog

When I started this blog back in 2004, I wanted it to be a single location for me to publish on any and all topics that piqued my interest. However, events that I have planned for the future (more on that later!) make me think it would be wise to split the blog in two: one for more professional topics, and one for those that are more personal.

This existing .com blog will continue to be where I publish regarding technical, development, programming, management, and other professional topics. The new .org blog, will be "everything else," including the political and economics posts that some of my readers love and others loathe.

The non-development-related posts on this blog have already been moved over to the .org location, and will disappear from this .com site soon. Short of adding rewrite rules for *every single post* that is now only over at the .org site, I can think of nothing that will keep existing links to those posts from breaking. My apologies to those of you who are affected. Comments, etc., will be retained.

Pretty soon, I'm going to change the hosting and the theme here as well. With any luck I'll have an announcement thereafter for all the remaining technical readers.

Thanks for your patience, everybody!

UPDATE (9:48pm): Turns out it was relatively easy to select all the post IDs on the .org site and build a list of Apache "RedirectPermanent" directives on the .com site, like so:

RedirectPermanent /archives/6 http://paul-m-jones.org/archives/6

That's courtesy of Apache mod_alias, not mod_rewrite, which is nice.