Learning About Dependency Injection and PHP

May 18th, 2011 § 31 comments

Over the past few years, there are a few concepts and programming patterns that have muscled their way into the hearts and minds of PHP developers from other languages and programming communities. These concepts range from the MVC application architecture as well as various modeling techniques (think ActiveRecord and Data Mapper), to a pure shift in the way we think about application architectures, like aspect-oriented programming (AoP) and event-driven programming. Perhaps it’s because PHP has been adopted at an enterprise level thus increasing the demand for what developers might call enterprise quality programming patterns, or perhaps it’s simply because of PHP’s ever evolving object model that makes new things possible. After all, who doesn’t like new shiny things? Whatever the reason, one of the newest concepts (at least over the past 3 years or so) that has emerged as one of our heated topics of debate is how to manage object dependencies. Interestingly, the argument of how to manage dependencies is generally named by the solution which its proponents give as the solution: dependency injection (the abstract principle is actually called Inversion of control).

In any circle of developers that are of the object-oriented persuasion, you’ll never hear an argument that dependency injection itself, is bad. In these circles, it is generally accepted that injecting dependencies is the best way to go. Injecting object dependencies in PHP looks like this:

That’s basically it. There are many variations of this: setter injection, interface injection, call time injection, in addition to the above mentioned constructor injection. These are all valid ways of injecting the dependencies into the consuming object. Ultimately, the goal here is to avoid this:

The above code is an example of a violation of the Hollywood Principle, which basically states: “Don’t call us, we’ll call you.”.

Yet, this is not the heart of the argument. Perhaps it was 4-5 years ago in the PHP community, but it’s not anymore. The heart of the argument is not should we be doing it, but how do we go about doing it.

This article is not about the intricacies and implementation details of DI containers and DI frameworks. It’s also not about the various ways and means of injecting dependencies into other objects, or which method might be better. In fact, this article has no opinion if injecting dependencies is even good for you or your application. This article is an exploration how adopting any DI framework for PHP affects the lifecycle of a project, both the code as well as the developer, team or organization that is constructing it.

A Brief History of Dependency Management In PHP

It is important to know why PHP is as popular as it is, after all, it’s this popularity that DI Frameworks fight against for adoption inside a PHP application framework. To understand PHP’s popularity, history, and evolution, let’s look at this code:

From the beginning, we’ve been trained into thinking that our dependencies are magically managed. As you can see above, the mysql_query() function, while it will accept a connection resource, does not require it. In fact, if it’s not supplied, it will use the first open mysql connection it can find inside the PHP runtime. Assuming that the above mentioned delete-user.php script is part of a larger collection of PHP scripts, which we will call “the application” … it is important to note that even this script itself is pulling in its dependencies instead of them being injected. For all intents and purposes, the config.php, header.php and footer.php are all dependencies of this script, much like other scripts similar in nature to this delete-user.php. To sum it up, if there is a new dependency that is now required by the business logic portion of this application (ie: the lines between the header and footer), they now have to be introduced to all scripts in this application. This does not exactly adhere to the DRY principle.

But, let’s take a step back and look at this snippet of code from the organizational perspective. To do this, we must first understand the various phases of the code’s lifecycle within any organization. For the purposes of this example, let’s assume that from idea to production, code will go through the following phases: development, build, deployment, to application start-up (in production). If this were a C/C++ or Java project, code will have been written (developed), it will have been compiled (built), then it would have been packaged or some deployment tool’s process invoked (deployed); it them would have been run (executed via some startup script, or executing a binary.) PHP, and Perl at the time, achieved all of the same objectives but in fewer steps making it a wildly popular platform for highly iterative web projects. This same application in PHP would have been coded in some text editor (developed), and FTP’d up to a production server (deployed). You’ll notice that it neither had to be built/compiled, or started on the server since the target, Apache, was already running with PHP embedded into it. For all intents and purposes, a cheap and easy FTP tool was both the build and deployment tool for this application’s lifecycle.

It was this simplicity that made PHP the popular choice for web applications. This popularity was attained because the simplicity of the PHP platform allowed for two extremely important facets of development to emerge: the idea of building an application became approachable to even the novice individual, and without all the cruft that came along with the application lifecycle, building and deploying applications in PHP increased PHP’s “fun-ness” factor.

While this style of building applications allowed for a proliferation of PHP applications to be developed, there was in fact a negative side to be revealed later in time. As applications quickly grew, their ability to be maintained decreased. We give them the name “Spaghetti code”, and for all the right reasons. Objects, if they were even being used, were generally wrappers around procedural functionality. So object dependency management wasn’t even a consideration for most developers. Looking back, perhaps it was this original simplicity that allowed developers to create applications without even having to know what a dependency was or how to find it. In any case, as these applications grew uncontrollably, maintaining them and hacking them started to lose the PHP fun factor exponentially.

A Brief History of DI Frameworks

As PHP developers started identifying the problems with their Model 1 applications, they started looking for solutions in other programming communities. At this time, the Java community was still heavily rooted in the enterprise/software development/software engineering world, and problems such as dependency management already had some interesting solutions. Most notably, there was the Spring Framework, who’s primary facility for dependency management was a component called the IoC Container, or the Inversion of Control container. This container managed the fully lifecycle of object creation using callbacks. This meant that you no longer has to use the “new” keyword (the same new keyword in PHP). Also, it wired the dependencies for you at instantiation time. This meant that you no longer had to concern yourself with how dependencies were injection; be it through the constructor, properties or setter methods. The Spring Framework was one of the first frameworks that encouraged the use of definition files to manage the knowledge required to wire all your dependencies together. True to form in the Java community, these definition files were created in XML.

As it might seem, this is indeed a deviation from the PHP philosophy that had made PHP so popular. PHP allowed you to write the most minimal amount of code to complete your application. In the Java/DI world, particularly with the Spring framework, you had a much richer application lifecycle. Not only were you developing code for your appliation, but you were creating code about code to manage code. This is known as meta-programming. In addition to this meta-programming that was going on, you also now had this compilation phase required by the Java platform which was generally tucked away inside your build time tasks. Moreover, this application had to be deployed (there were generally tools for this too), and (for good measure), due to the platform, your application had to be started. Needless to say, this application lifecycle might seem heavier, for lack of a better term, to the average PHP developer.

Since then, several frameworks have cropped up that sport some kind of dependency management. Before this technique was picked up in PHP, they were all heavily rooted in the Java and .NET communities. A quick google search will return a few notable names like PicoContainer, Spring.NET, Unity, Butterfly and google-guice to name a few. These frameworks attain popularity since they attempt to ease some of the burdens that DI places upon the developer whether it be by using reflection to create definitions, or even adding an annotation system so that DI definitions can be written inside the code they are set to manage.

DI and PHP

To understand the attainability of having a dependency management framework for PHP, one should first understand how the counterparts in Java and .NET rely upon their respective platforms to do certain jobs. For a quick reference, see the images from this blog post. One of the more important facets to remember is that the expected application lifecycle of a Java/.NET application is much richer. You are expected to have build-time tasks. You are expected to have deployment tasks. And, generally, your application understand the difference between being in development, staging and production – so it can adjust how it runs accordingly. Moreover, the platform itself has facilities in place that aid the developer both in development time with code generation as well as in production.

PHP never expects or facilitates the usage of any kind of build-time tasks. PHP also does not have any kind of built-in annotation support (a meta-programming technique), nor does it have any kind of application scope or per-application memory space. What does this mean for someone who is creating a DI container? Let’s explore.

Development Time

General speaking, any time you are writing, altering or just shifting code around, you are in development mode, your application should be running in a development environment. The structure of your application’s classes, functions and files within the filesystem is probably changing with each time you click save. Dependency management systems require knowledge of your code in order to effectively do their job. This knowledge generally comes in the form of some kind of definition.

This definition can be created by hand, by the developer, generated at runtime by some application hooks, or generated with the use of a special tool. If this is done by hand, a developer is required to explicitly map the various functions/methods that will need to be called in order to inject a particular object dependency. The more dependencies you have, the more verbose this definition might become.

A better route would be to generate this definition file, after all, the code you’ve written, if written correctly will self-describe its dependencies. There are two options for generation, manual and automatic. An example of manual generation would be a developer giving a command line tool the minimal information it needs to be able to go parse your code, figure out the dependency map for itself, and generate some kind of definition to be used during runtime. Minimal information might include some kind of seed information like where to find your classes or perhaps what filters to use when inspecting classes. Sometimes, these tools might make use of special interfaces (also called interface injection) to understand that their purpose is to describe the various dependencies of the class implementing said interface. Another approach might be to utilize special annotations on classes and class methods that describe the various required and optional dependencies and how they are to be injected.

The same techniques employed in this manual approach could also be put to use in an automatic approach. In automatic approach, imagine this same command line tool from the manual approach was now a service of the application itself. While in development mode, it would run as often as need be in order to determine if code changes have happened. If they have, the service would regenerate the dependency definition file so that the rest of the application can utilize the dependency definition inside the DI container available to the application during runtime.

There are a couple of concerns that are specific to PHP with regards to dependency management. Since PHP is a share-nothing architecture with no application level memory, this definition would need to be loaded and parsed and put into memory on each request. The larger the dependency tree that you track, the larger the memory footprint of the dependency definition graph. Furthermore, since this definition has to be loaded on each request, if it is in a non-native format (meaning anything other than PHP code), there are certain costs with converting this format, be it XML, YAML, JSON, or INI to the in-memory structure that the dependency management container requires. What’s more, the PHP platform does not keep track of file changes. So without some kind of user-land tracking, it is hard to know what files during development have changed. Thus, your dependency management system, if it’s taking an automatic approach, would have to rescan the filesystem for changes upon each request during development – which has its own consequences.

Deployment Time

When one is done writing code and is ready to push this application into production, the act of pushing this application is called deployment. The mode for this application is now considered “production”. In production, you can be sure that the structure of your code is stable and will not change, thus your dependency graph is now safe from changes too. Since this is the case, there is no longer a need to keep updating and regenerating this dependency definition file like you were during development.

Even though the definition is no longer changing, there still is the concern about how expensive it is to load this definition each request. Naturally, the cheapest form of definition would be a PHP array or structure describing the definition that can then be loaded in-memory. Other file types like XML, YAML, JSON, etc first have to go through a parsing phase before they can be used. This activity of parsing these files could be expensive, and could benefit from some kind of caching. Caching the definition in some way shape or form, would ensure there is minimal overhead per-request when the application is using this dependency management container.

Other Observations & Criticisms

It is important to realize that dependency management solutions in and of themselves are, in all the available words, full frameworks. They require that you understand both their philosophy as well have a minimal understanding of what facilities they are offering in order to use them effectively. To understand the true benefits of any framework one must first know the pain points the framework is attempting to solve. Seeing the end result of a framework without knowing what it is facilitating might lead to one to dismiss it as overkill or unintuitive. For example, take the following code (typical of dependency management systems)

If you encounter this line of code without fully understanding the dependency injection container being used, you wouldn’t be able to appreciate its usefulness. You could instantiate your Application\Model\UserRepository yourself, sure, but you’d also have to locate and inject the database adapter to use and into that you’d have to inject and load the configuration for that database connection. If you are doing this in multiple controller actions, there is a lot of repeated boilerplate code that is required to “wire” the UserRepository object. Internally, the DiC object is loading and consulting a definition, creating objects, injecting those objects, and returning the requested object that has been fully wired and ready to use.

The above code also demonstrates two common criticism of dependency management frameworks, which is also a criticism of frameworks in general. By using this framework, you are moving further away from the facilities of the language or platform itself. Instead of using the “new” keyword to create a new object, you’ve asked another object to create this requested object for you. What this has done has shifted developers away from utilizing the language’s well understood API and onto the framework’s API. Additionally, this kind of code is not easily understood by IDE’s. While special features could be added to the IDE to support this framework, it does not inherently know what kind of object is being returned by the $dic->get(..) method call.

Summary

While dependency management frameworks have clear drop-in benefits, there exist a few considerations that have unknown or unexplored consequences. For example, if the benefit is such that all dependencies are managed, and all a developer has to do is configure it, does that encourage deeper object graphs when creating classes and class dependencies? If so, what is the performance impact of these deep object graphs, particularly on the PHP platform. What are the memory implications of such object graphs, what are the speed implications of them? Furthermore, if one needed to debug an object that has been generated by a dependency management framework, is that easily possible?

At the end of the day, whether or not to use a dependency management framework is a matter of cost versus benefit. In order to be able to make an informed decision, a developer should consider a few scenarios. First, one should know what code might look like with and without this new framework. This will give an indication of the cost/benefit at the code level, does it actually save lines of code, and developer headaches? Secondly, one should consider how much added knowledge a developer or a team of developers need in order to understand this framework. Lastly, one should consider what kind of performance impact implementing this new framework has on the application’s throughput.

Tagged , , , , ,

  • Drak

    A trick for your IDE when using $dic->get(‘foo’) is to write it like

    This was your IDE will be tricked into understand ‘foo’ – useful for auto complete anyway.

  • Pingback: Ralph Schindler on Dependency Injection in PHP | PHPtrends.net

  • Craig

    Depending on the IDE (works in Netbeans!) Drak’s approach can also be employed without having to store the variable on the current object, by placing the doc comment inline, like so:

  • John Kary

    @Drak Your advice for adding @var Some_Foo is good, but I wanted to caution users against making your objects aware of the DIC itself. Having $this->dic means you’ve injected the DIC into the object at some point. By doing this you’ve made your object more tightly coupled to the DIC itself.

    The better approach would be to wire your object using the DIC to inject the Some_Foo dependency into your object, rather than count on your object to pull the service it needs from the DIC.

    When first encountering a DIC, many people think about injecting it into their Controller and simply replacing ‘new’ calls with calls to the DIC. Because, after all, the Controller’s job is to take runtime data and route it to other objects to process. But this is bad practice. Your Controller should only be aware of the actual objects it needs to interact with to do its job. It should not reach through the DIC to get those objects.

    Check out this great post on wiring Controllers as Services for Symfony2. It will show a refactor for how to go from reaching through the DIC to get services to how the class will look when being injected with objects by the DIC. Even if you don’t use Symfony2, everything should look familiar after reading this post:

    http://miller.limethinking.co.uk/2011/04/15/symfony2-controller-as-service/

  • Pingback: Dependency Injection mit PHP (Link!) - Geek Pub

  • Drew Pull

    Interesting, but this misses the mark for me… dependency injection is *not* about DI/IoC containers.

  • http://ralphschindler.com/ Ralph Schindler

    @Drew Pull: precisely why I stated this was not about injecting dependencies. We all agree (at least most developers agree), that injecting dependencies is the way to go- I offered a simple example of what it looks like to inject a dependency. This article is about how we manage dependencies when they grow and when the code to wire such dependencies (typically boilerplate code) grows. By boilerplate, I mean this:

    If you find that bit of code finding its way into many different controllers (assuming MVC), you need to DRY that up. One solution is a service locator, another solution is a DI Container, another solution is a service locator derived from a DI container, there are other solutions too.

    Point being, the solutions to the “how” problem are frameworks and containers, this article explores the pros and cons (albeit at a very fundamental level) of containers and frameworks in an interpreted/shared-nothing/scripting platform like PHP.

    I’ll be the first one to tell you that one-man/small projects don’t gain from DI as much as larger scale, multi-team member, process driven applications.

    -ralph

  • http://miller.limethinking.co.uk Richard Miller

    Excellent article Ralph.

    @Drak, as John says requesting services from the DIC in your classes is not an ideal way to do DI. doing this introduces a dependency on the DIC which is a problem for several reasons. It menas that all classes requesting that object from the DIC will get the same object so you lose the ability to inject different implementations into different objects. It also means that your code cannot be used without the DIC or with an alternative DIC. . Additionally in tests you need to use the DIC or mock it. Additionally your code cannot be used without the DIC or with an alternative DIC.

    You can still get the IDE autocompletion by injecting the dependency directly using the constructor:

  • http://www.jblotus.com james fuller

    I enjoyed your take on dependency injection containers. I ended up writing one myself without ever knowing wat to formally call it. DIC’s are the Way of the future IMHO

  • Drak

    @all I realise using a DIC to suck in dependencies is not necessarily a good practice, but I was just responding to a point in the article about the effect in the IDE (lack of autocomplete) and the way to solve that, if you choose to inject the DIC.

  • http://pinkhandtech.com/ pinkhand

    Wonderful
    @thanks Richard for telling us how to get the IDE autocompletion by Injecting the dependency directly using the constructor.

  • http://www.tonymarston.net Tony Marston

    This article is yet another glaring example of where OO programmers deliberately try to make a mountain out of a molehill just to prove how clever they are. To me it proves just the opposite.

    In my long career in software development I have learned to follow a number of key principles:
    a) If it ain’t broke don’t fix it.
    b) If it doesn’t cause a problem it doesn’t need a solution.
    c) Keep It Simple, Stupid

    This “solution” is supposed to address the problem of dependencies, but what exactly is the problem? You cannot eliminate dependencies altogether as your software just would not work. If module A needs to perform some processing which is already contained within Module B then Module A simply calls Module B. This may create a dependency, but so what? It’s certainly better than having the code within Module B duplicated within Module A. This is what “Modular Programming” is all about, and Object Oriented Programming is supposed to be an extension of this paradigm by using “objects” instead of “modules”.

    The idea that you need to “manage” dependencies is also ridiculous. If I have the following code in Module A:

    $objectB = singleton::getInstance(“classB”);
    $result = $objectB->doStuff(…….);

    it is simple to understand and easy to modify. So why change to a different method which is less simple? What are the costs? What are the benefits? By introducing another layer of management you are moving towards the situation where there are too many chiefs and not enough Indians. Your application will contain a small amount of code which does useful work and a large amount of code which manages the workers. It will take longer and longer to get things done, and longer and longer to adapt to changes. And you call this “progress”? Pull the other one, it’s got bells on!

    There’s a saying in the world of aviation:

    “There are old pilots and bold pilots, but there are no old bold pilots”

    In the world of software development we now have:

    “There are sensible programmers and OO programmers, but there are no sensible OO programmers”.

    When you say that “injecting dependencies is the best way to go” you forgot to add “in cloud cuckoo land”. Those of us who have to live in the “real” world will continue to ignore such ridiculous concepts while still being able to write effective software.

    • me

      Tony Marston I agree with you 100%
      have been working in IT 16 years, 12 of them on the web

    • http://www.graphicmist.in Manish Kutaula

      I totally agree with you what you have said and at the same time disappointed on your thoughts.
      As you say:
      “There are sensible programmers and OO programmers, but there are no sensible OO programmers”

      the goal is to be a sensible OO programmer even though it might not be possible to achieve. Its in the human nature to achieve that perfection, that artistic beautiful structure and design of code. Thats why we are seeinf PHP evolved from shit to a beautiful language.

      At the end it all personal perspective how you see it.

  • http://artur.ejsmont.org/blog/ Artur Ejsmont

    Very nice article.

    I totally agree that your classes should not depend on the DIC itself. It is a bad idea. What you can do to easily avoid it and still have the IDE support is to add constructor that takes dependencies as arguments and then sets them on the instance private members. Each member has comment defining the type for NetBeans (and others) to know the type.

    Dependencies control is a huge issue in PHP and people should focus more and more on how to manage them and think carefully which objects should be able to talk to which objects before throwing everything into Zend_Registry ;)

    thanks

    art

  • http://marcelog.github.com/Ding Marcelo Gornstein

    You might want to try Ding (http://marcelog.github.com/Ding) which is an inversion of control and dependency injection container for PHP 5.3, based on Spring(tm) for Java. It has AOP, MVC, and custom events support. It supports XML, YAML, and some JSR 330/250 annotations for bean definitions

  • Pingback: Linkdump #55: PHP – Personal Home Page. « Tomasz Kowalczyk

  • Pingback: » Zend Framework 2.0 Dependency Injection Programming the new world: Programming your life and the net, one day at a time

  • Pingback: Dependency Injection unterschied zum Factory – Pattern? - Geek Pub

  • http://objectic.cc/ Niko Kivelä

    @Tony: You want a class A (client) to call B (supplier). B serves A by DbC (http://en.wikipedia.org/wiki/Design_by_contract) without A having to worry about the dependencies for B. You really can’t use this as an argument to invalidate need for dependency injection, it’s only a contract between two.

    The simplest case will work until you start dealing with more complex application in which the flow isn’t that sequential anymore. Objects could reside anywhere in application divined by their responsibility and behavior, not by where they are ment to be run. See separation of concerns (http://en.wikipedia.org/wiki/Separation_of_
    concerns).
    DI serves this purpose well (or Locator) for users that they don’t have set up dependencies from other classes using other classes and consider objects’ life cycle management. It all becomes clear when you work in a bigger teams and/or have over 200+ dependencies to take care of.

    (I didn’t even say anything about how hard it could become to support testability without allowing DI to swap concrete/mock/components).

  • Pingback: Geek Pub » Blog Archive Dependency Injection mit PHP (Link!) - Geek Pub

  • Pingback: Geek Pub » Blog Archive » Dependency Injection unterschied zum Factory – Pattern? » Geek Pub

  • sunshine1988

    To retrieve the auto complete of IDE when you get Obj from DIC, just add a “@return …” comment.

    /**
    * Get some obj
    * @return {the obj className or whatever it extends or implements}
    */
    public function getSomeObj(){
    //do something
    return $someObj;
    }
    It works at least in ZendStudio and,I don’t test any other IDEs!
    PS: sorry for my poor English~

  • http://www.mohitsharma.net Drupal Programmer India

    true said , this Dependency Injection and PHP is going to help us lot on better programming ,
    thanks to Dependency Injection and PHP

  • MardiGrass

    Nice!
    Another way of making things complicated.
    If it was me, I would have called it HideAndSeekInjection.class.or.interface.or.trait.php
    This does solve what?

  • http://brazen.ca Michael Ekoka

    Excellent article.

    In the comments I saw some reactions to examples where the DI Container is
    itself a dependency of a class.

    Yes, strictly speaking when following the proper DI/IoC guidelines, objects should not be aware of the container. But there’s dogma, and there’s pragmatism. Because PHP isn’t like other languages a pure implementation of the IoC pattern would create some problems for it, it needs to be adapted.

    Instead of blindly transpose one community’s practice onto another, it would be
    smarter to first understand the problems it was originally trying to alleviate
    and see where we can make compromises to have some of the same benefits for PHP, without hefty costs.

    The biggest aim of DI/IoC is to make objects more contained and testable. The
    cost is that you need to load all dependencies of an object prior to use it.
    Bootstrap, router, controllers, models, helpers and all of their respective
    dependencies, all in one go. Sounds like a heavy process. In languages such as
    Java and C#, the application initializes once and then resides in memory. The
    DIC can afford to setup such a rich and heavy object graph as it pays the price
    only once. PHP on the other hand has to do this *upon each request*. This
    doesn’t sound optimal to me.

    How do you go about resolving the drawback then?

    Unless your PHP application is really small or permanently resides in memory, a
    more sensible and practical compromise would be to reduce your objects’
    dependencies to only one: the DIC itself. Your objects are still very testable,
    the difference now is that in addition to mock the normal dependencies, you
    also have to mock the DIC registry.

    So, not to put a damper on PHP devs’ enthusiasm, but unless they use their DIC like a registry, I don’t see how it would make sense to even consider using one.

  • Pingback: Refactoring to interfaces | Daniel Watrous on Software Engineering

  • http://www.evinw.com Evin Weissenberg

    Enjoyed reading the article.

  • Kevin Earley

    Ralph. I have in the past been a fan of your written work, but I am compelled to I disagree with what you have conveyed in this article. I think dependency injection is, in general, a poor pattern for many reasons which include “using it because”, and the many points made so eloquently by Tony Marston’s article found here: http://www.tonymarston.net/php-mysql/dependency-injection-is-evil.html.

    I read his original posting here on your site, but for some reason it was removed. The censorship of other’s ideas generally intrigues me, so I investigated further to see what ideas you tried to hide from your readers. Interestingly, his arguments were stronger than yours and made more sense to me and my buddies.

    Because you tried to hide ideas that disagreed with yours, I no longer trust your insight and do not plan to read any more of your writings.

    Thanks,
    Kevin

    • http://ralphschindler.com/ Ralph Schindler

      @Kevin

      You are free to disagree with me. As I’ve stated a number of times in many different posts, any given pattern needs to be justified by your team/project/organization’s general philosophy and standards. If DI doesn’t pass those tests, you are free to use globally accessible objects. WordPress does this and it works out just fine (to name one of many projects.) Use the patterns that makes the most sense and bring the most order to your projects.

      On the other note, Tony’s comment is and always has been comment #10 on this post, you can even see people have had exchanges referring to his comment. Since he failed to update his post, I will post here what I sent to him after reading that nearly a month ago (I’ll redact the email addresses):

      I was under the impression it had been removed because when I went back to
      your blog the next day my comment was not there. I don’t know whether it was
      a browser issue at my end, or some hiccup at your end, but it seems to be
      resolved now.

      Tony Marston

      http://www.tonymarston.net
      http://www.radicore.org

      —–Original Message—–
      From: …
      On Behalf Of ralph@…
      Sent: 19 September 2012 15:51
      To: webmaster@tony…
      Subject: Your comment on my blog post …

      Hey Tony,

      In reading your rebuttal to my DI article, I noticed you were left with the
      impression that your comment was removed. This is not the case, in fact,
      other people commenting have responded to your comment (several months
      later). I am not sure why you think the comment was removed.. the site is
      running WordPress (maybe that\’s part of the problem?), but even then, I
      know the only place comments are not displayed is on index pages of the site
      (not the actual article page).

      I don\’t delete any genuine comments, regardless of the tone or perspective.
      The only comments I delete are genuine spam (marked by WordPress\’s spam
      filter, and some trackbacks that have nothing to do with the content of the
      article.)

      Thanks,
      Ralph

  • Pingback: Yang Baru Dari Zend Framework 2 | 0prek

What's this?

You are currently reading Learning About Dependency Injection and PHP at Ralph Schindler.

meta