Innovate faster and cut risk with PHP experts from Zend Services.
Beginning to advanced PHP classes to learn and earn global certification.
Help me choose >
Submit support requests and browse self-service resources.
Matthew Weier O’Phinney
What is a PHP framework?A PHP framework provides the core infrastructure for turning an incoming HTTP request into an HTTP response. That’s because PHP is most often used for web development. At a minimum, frameworks manage HTTP negotiation, dependency graphs, templating, and error handling.
A PHP framework provides the core infrastructure for turning an incoming HTTP request into an HTTP response. That’s because PHP is most often used for web development. At a minimum, frameworks manage HTTP negotiation, dependency graphs, templating, and error handling.
There are many frameworks to choose from including Laminas (formerly Zend Framework), Laravel, Symfony, Nette, Yii, and CakePHP. Deciding which one is best for you is easier when you compare how each framework addresses the following 12 capabilities in relation to your requirements:
The first four capabilities listed are the most critical. If your framework provides them, you can save time and improve application quality. And with some in-house architectural and structural guidelines, you can develop anything. The importance of the last eight capabilities will depend completely on your requirements.
To help ensure the framework you choose can meet your requirements today and into the future, it’s important to review how it:
For example, for each request, the framework should be able to:
To match a request to a handler, you need to obtain the handler and all its dependencies. You can hand-wire handlers and dependencies in your code. However, when you take this manual approach, applications quickly become an unmaintainable mess. And re-purposing code for re-use, or moving code to new locations based on new requirements, can make this approach even less attractive.
Frameworks can automatically match every request to a handler by using "controllers" or "request handlers.” Controllers and request handlers are generally written as PHP objects. And based on what they do, they may require other objects as dependencies.
To simplify code management, most modern frameworks provide dependency injection containers for managing the various handlers they expose, and the services that act as their dependencies. If a framework uses dependency injection, it should comply with the standards outlined in the PSR-11 Container Interface specification from the PHP Framework Interop Group (PHP-FIG).
Most modern web applications have dynamic content that shares a common display structure or template. To populate a template, applications need to pull data from a source, such as a database or web service, and then pass it to the template to render the final page.
Traditionally, most frameworks provided their own template renderers. However, you can simplify your code and maximize long-term flexibility by using a framework that provides only an integration layer to templating engines, which allows you to choose the one you prefer. This is the approach taken by SlimPHP and Mezzio.
No web application is perfect. At some point, you will hit error conditions. Production-ready PHP applications disable the display_errors directive in php.ini. However, if no other error handling mechanism is in place, a user could get the dreaded White Screen of Death (WSOD) in response to their request.
To avoid errors including the WSOD, evaluate the framework’s error handling options. For example, when an error occurs, does the framework automatically:
Many frameworks provide rapid application development (RAD) tooling to manage repeatable tasks such as:
RAD tools can save time because instead of writing boilerplate code to manage these types of tasks, you can issue a single CLI command and move on to the next thing. Such tools are particularly nice when you need to quickly prototype an application.
I'll note, however, that RAD tools often come at an extensibility cost, so consider your long-term goals. In addition, RAD tools generally have a small impact on overall time savings across an application’s full lifecycle. Really, you’ll spend the most time on your business logic instead of a few seconds here and there on repeatable tasks. That’s why RAD tools should rarely be a deciding factor when selecting a framework.
Early PHP frameworks tended to offer database abstraction. The landscape has since changed dramatically and today, database abstraction is something that can be delivered by standalone libraries. Additionally, data sources vary widely; today we also have:
Although it can be useful to have data abstraction library built-in to your framework, it’s advantageous to use a dedicated DBAL or ORM library because:
Framework authors often write code specific to their needs, and then generalize how it works for wider applications. However, if your needs fall even slightly outside the framework’s capabilities, you will need to:
Context is key when looking at the flexibility and extensibility of framework capabilities. For instance, you may want to:
To help avoid framework lock-in, it’s important to insulate yourself from framework changes. This includes protecting your ability to extend framework capabilities and switch frameworks. To achieve this flexibility, I recommend following the Interface Segregation Principal when you code. By doing so, you:
If possible, try to stick to interfaces defined by the PHP-FIG, because they are designed to decouple your application from specific implementations.
Ensuring the integrity of how your application marshals incoming data and populates your responses requires testing of components including MVC controllers, middleware, and request handlers. Some frameworks provide specialized tools for testing the entire request and response lifecycle through an application instance, complete with custom assertions. These kinds of tools can be a huge boon towards understanding how all parts work together, and they can simplify and give structure to your testing strategy. However, they also tie you directly to your framework, at a very fundamental level.
To decouple HTTP request lifecycles from a framework, look for other ways you can test. For example, The PHP League provides a package for validating that an API that consumes PSR-7 HTTP Messages conforms to an OpenAPI specification. This can be used regardless of the framework — though it may require custom scaffolding to work with an application.
Another library, helmich/phpunit-psr7-assert, provides an easy way to assert against PSR-7 HTTP messages. It can also be used in any application that uses that standard.
To perform framework-independent integration or functional testing, another option is to use external, black-box behavior-testing systems such as Codeception or Selenium. With these tools, you can create tests that define the client conditions and actions, and assert against what they receive in response.
For all applications, it’s important to determine its acceptable level of performance. If you have a handful of users, and they all understand what is being done is computationally expensive, your requirements will be quite different than a website that supports hundreds of thousands of customers daily.
Many users turn to their framework’s baseline performance tool as a guide. They can provide metrics that show how fast the framework can return a response. However, the numbers can be misleading. The response-time metrics will be based on a configuration that’s set for minimum conditions. As your application grows, its bootstrapping costs will typically increase, adding to response times.
To maximize performance potential, consider:
The complexity or simplicity of your PHP deployment will be determined by system complexity. For example, how many systems — such as databases, caching services, and log aggregators — are involved? Will you be scaling horizontally?
Using frameworks adds more questions and potentially, complexity. For example, some frameworks will require you to pre-compile certain pieces of the application before you deploy. Depending on your configuration, you may also need to ensure certain environmental variables are set and present on the target system.
Some frameworks provide tools that help prepare your application for development, including Platform-as-a-Service (PaaS) solutions. It’s helpful to ask the following questions to see if they meet your requirements — or be flexible enough so you can adapt them to meet your needs:
If you are handling any user data, you need to be concerned about security.
PHP provides many security tools and the number and quality increase with each minor release. However, when evaluating a framework’s security capabilities, see if it:
Many PHP applications support mission-critical websites and web services. Being able to contact a certified PHP expert 24x7x365 may be important to you. If so, check if the framework has support options.
As a Zend employee, I’ll share that you can get long-term, mission-critical support for Laminas (formerly Zend Framework). The offering also includes consultative guidance for using Laminas as well as ready-to-go adapters for commercial PHP applications.
Development Lead for the Laminas Project, Zend by Perforce
Matthew began developing on Zend Framework (ZF) before its first public release, and led the project for Zend from 2009 through 2019. He is a founding member of the PHP Framework Interop Group (PHP-FIG), which creates and promotes standards for the PHP ecosystem — and is serving his second elected term on the PHP-FIG Core Committee.