Unfortunately we have no framework in use

Stefan PriebschArne Blankerts |

The history of PHP frameworks begins in the middle of the noughties, in 2005 to be exact. Although PHP has been around since 1995, it was not until version 4 that rudimentary support for what might be called – with a lot of good will – object-orientation. However, this did not prevent some daredevils from taking their first object-oriented steps. They published libraries and classes, which mostly simply bundled certain functionalities: PEAR, the PHP Extension and Application Repository, was born. And even if these solutions have little to do with what we might understand as a framework today, the modular concept of PEAR can also be found in modern frameworks.

The next generation of PHP frameworks required version 5 of the language, which was released in 2004 with serious support for object-oriented development, the Dot-com boom, and last but not least David Heinemeier Hansson. Whether one should be proud of having promoted the Dot-com boom from PHP's point of view today is probably a question that can be excellently discussed or even argued about. What is undisputed, however, is that David Heinemeier Hansson with his framework Ruby on Rails had a great influence, also and especially on the PHP world, and probably still does today.

At first, the PHP community looked with envy at the early success stories about how productive programming can be with a framework such as Ruby on Rails. Admittedly, a comparison between a programming language and a framework does not make much sense, but who in today's (media) world still asks about the usefulness of comparisons?

The standard example of Ruby on Rails applications, the creation of a blog in less than 10 minutes, was impressive, but is deceptive about the complexities of a real application with serious business logic. And this is before we get to the problematic use of Active Record and the strong coupling of code to the database behind it.

Probably also out of fear that PHP – not least because of the Rails framework – could lose market share to Ruby, and because there were hardly any serious PHP frameworks available at the time, the company Zend announced its own open source product: The Zend Framework.

However, it would take about two years until its first release on June 30, 2007. Time in which other development teams also worked on their frameworks for PHP, and some of them achieved a quite remarkable spread. Among the best known frameworks, the first ones were probably CakePHP, Agavi and Symfony 1 in 2005, followed by CodeIgniter in 2006 and its fork Kohana in 2007.

Of course, not only generic frameworks were developed, but also more or less turnkey solutions for content management systems, interactive portals, or the creation of online stores. Besides Typo 3 and Drupal, especially Magento became one of the most popular (and often hated) platforms for e-commerce. Fun fact: originally touted by Zend as a showcase for the power of its own framework, Magento 1 used very few parts of an early pre-release of the framework, and even then the underlying concepts were bent almost beyond recognition.

The increasing variety of frameworks and concepts quickly led to the question of which framework was the best. Of course this question seems to be obvious, if one may not (anymore) ask which programming language is the best. The discussions that follow the attempts to answer this question are of course highly religious. After all, there is hardly any topic developers can argue about as much as this, except maybe about indentations and where to put curly braces.

Towards the end of the noughties, various conference organizers therefore thought that a public framework discussion might be entertaining. If the users of individual frameworks were already inclined to bang their heads about whose framework was the better one, what would happen if core developers of different frameworks were to be brought together in a panel discussion? We remember a conference in which an organizer had placed a loaded nerf gun in each seat as a precaution.

What happened then must have been a bitter disappointment for the organizers: The representatives of the different frameworks, who knew each other anyway, expressed great respect for each other, praised the technical advantage of the "competition" here and there, and told where they had been inspired by each other. The "War of the Frameworks" conjured up in the title of the event had never existed like this. The PHP community, even if it doesn't always seem so from the outside, has always been strongly interwoven.

If you don't have to strive for market share to further increase your own sales and keep on publishing new business success stories, you can be inspired by ideas, concepts and solutions of others, just like PHP as a language did and still does. It is this "learning from each other" that accelerates innovation. In an open source world, this is even better and even faster, because you can easily view the source code of others without technical and legal hurdles and – depending on the license – even take it over directly or integrate it as a component in your own solution.

Fabien Potencier, founder of Sensio Labs and father of Symfony, has rendered outstanding services to the PHP community like no other. He has always known how to look beyond PHP and learn from other languages and their frameworks. In this way, he has brought new ideas and many best practices to the PHP community. Symfony has been an innovation driver in the PHP world all these years and has influenced many other solutions and frameworks. Of course, you don't have to agree with all decisions, concepts and resulting solutions, but many innovations are – at least in the world of PHP frameworks – hard to imagine today without them.

The consistent use of Dependency Injection (DI), for example, which should be a matter of course in object-oriented programming, was not always the obvious choice in PHP development. At the Unconference track on the sidelines of a ZendCon in Santa Clara, where there was a session on Dependency Injection, Fabien, Stefan and one of the core developers of Zend Framework, Ralph Schindler, sat together and discussed the pros and cons of DI. At first, Ralph was not convinced why and how Dependency Injection should be used at all. Obviously, Fabien and Stefan's arguments were convincing, because in the next release, Zend Framework came with a new component, a Dependency Injection Container (DIC), written by Ralph Schindler.

Interestingly, despite its name, Zend Framework was initially marketed as a loose collection of components that could be used together and followed a relatively uniform development scheme. This is very different from many of the other frameworks, which had a fixed, rather monolithic structure following an "all or nothing" principle and are therefore also called full-stack frameworks.

Which leads us to an exciting question: What actually is a framework? If you ask the Internet, you will get, as so often, countless explanations, some of which even contradict each other. In somewhat academic terms, a framework is simply an inversion of control. In practice, this means that an application does not control the control flow itself, but leaves this to the framework. Thus, recurring processes can be mapped generically, so that the application developer can concentrate on writing the application itself, whose components are then called by the framework.

Not surprisingly, most frameworks in the PHP world are concerned with abstracting HTTP requests and want to make it as easy as possible for the developer to create an application and integrate it with the Internet.

Many frameworks claim to rely on the MVC design pattern. The fact that the Model-View-Controller Pattern, which Trygve Reenskaug invented in 1979 for desktop applications in Smalltalk, cannot function conceptually on the web and across client-server boundaries, has been and is simply ignored. The consequence is that nobody can answer exactly which code actually belongs in the model and which in the controller, not even the authors of the respective frameworks. Only when it comes to the view, most people more or less agree.

But no matter which HTTP framework you choose, the control flow for responding to an HTTP request is always the same: Depending on what kind of request is present, you have to decide what code to execute – a process called routing. In order to display the result, HTML and thus the view just mentioned is usually used. Errors are "converted" into corresponding HTTP error codes or, in the case of form processing, prepared in a user-friendly manner.

By the way, form or data processing is also a typical use case for a control flow reversal framework. Instead of implementing the control flow, the application developer only defines the form itself, determines which values it should be pre-populated with and then defines the validation rules with the corresponding error messages. Afterwards, all that remains to be done is to define which action(s) are to be executed in case of success and which in case of error. The control is then taken over by the inversion-of-control-container, in the simplest case a self-written abstract base-class.

Even a supposedly modern CQRS framework doesn't look much different, except that a distinction is made between command and query, which are routed separately. In addition, commands normally do not return content, while queries obviously serve to deliver content. The fact that this content is ideally already statically generated outside the request and thus available in a form that optimally matches the query does not change the actual processing flow much.

It gets interesting when requirements change and this leads to the fact that basic assumptions, especially of the framework, no longer apply: What happens if instead of HTML the response is to be JSON or the same business transaction must be processed independently and without a triggering HTTP request? What does it look like when instead of a complete HTML page small fragments are needed in different formats? Classic full-stack solutions such as Magento or Typo3 still suffer from the fact that their architecture is not really designed for use cases like that.

Those who have not developed the business logic of their own application in a cleanly isolated manner, but closely interlocked with the framework, also have a problem here. The solution is often a tool like wget, which can be used to trigger an HTTP request from the command line. Or sometimes complex additional technologies are used to cut, parse, or convert the delivered page.

Interestingly enough, the realization that the framework used so far can no longer cover all requirements rarely leads to extracting the actual business logic first. The rule seems to be that one tries to bend the current solution further and further, thus losing any chance of an upgrade or directly repeating the same mistakes when migrating to another framework.

Most framework vendors have learned their lesson: If a migration path from Zend Framework 1 to version 2 was virtually non-existent, for example, current frameworks are keen to maintain backwards compatibility with earlier versions as far as possible.

For us, it is always interesting to experience in our everyday consulting work that developers literally apologize to us for not having a framework in use. Besides the fact that this is not true in most cases according to the above definition of framework, a completely unnecessary devaluation of one's own work shines through. You neither have to be ashamed if you have developed your own framework that is tailored to your own requirements, nor should you be ashamed of using a standard framework.

A framework does not have to be – and perhaps even should not be – implemented as a full-stack solution but rather must efficiently solve exactly one task. In the ten years since then, there has been a clear trend away from full-stack frameworks towards so-called micro-frameworks such as Slim. This was triggered by the realization that a heavyweight framework that is designed to load a lot of data in order to dynamically assemble a complex HTML page from it is not necessarily suitable for answering AJAX requests from the frontend with high performance. With the possibly exaggerated trends towards microservices and containers, it seems that a definitive move away from large, monolithic software has taken place – if it weren't for the large chunks of legacy software that most companies still store somewhere in the data center in the basement.

The two most important lessons related to frameworks are: don't ask how to migrate from framework X to framework Y, but ask how to make your application independent of framework X – the rest comes naturally, and may be crowned with the interesting realization that you don't need that much framework after all.

And: a framework is a solution blueprint. It usually provides some useful best practices in the form of conventions, rules or documentation. You just have to keep in mind that nobody, not even the greatest framework in the world, has the right to be the "one and only way" to do something.

About the authors

Stefan Priebsch

Stefan Priebsch inspires with a combination of new ideas and field-tested approaches.

Arne Blankerts

Arne Blankerts has solutions ready before others have even understood the problem.