Making Zend Framework Components Compatible With PHP 7.2 & Is It The End of Monolithic Framework at Zend | Hear It From The Mouth Of The Principal Engineer at Zend Technologies a.k.a Mr Matthew Weier O’Phinney

About This Interview

This is the #39th set of PHP Interview to help aspiring PHP developers and PHP fans alike to get inspired by listening from those PHPeople who are already highly involved into the PHP Ocean and *being there* taming the waves and surfing better than ever to make themselves an Awesome PHP Expert both in their own eyes (for self-accomplishment) and for the PHP Community.

On the other side, this is an opportunity for new PHPers to get to know their “PHP Elders. I hope you will derive as much fun to read my interviews as I’m having by interviewing those awesome PHP people.

A Small Intro..

For those that are new to this blog, back in October 28, 2012 I hosted Mr Matthew Weier O’Phinney (MWOP) for the very first time on 7PHP, for a… wait for it.. PHP interview of course!

At that time, I also tagged him as the “Sir Alex Ferguson of the Zend Framework family“. And as of today July 2018, i.e 6yrs after, I still stand by this sentence. Why?

Just like Sir Alex, Mr Matthew, commonly known as the Supreme Allied Commander of Zend Framework (a special honorary title given to him by The Don of The PHP Community, Mr Cal Evans) has and is doing an outstanding work behind the scene for both Zend Framework and PHP.

I was lucky enough (and eternally thankful to the PHP Community) to have been in a room of PHP experts, at SunshinePHP Conference – in Miami Feb 2015, to hear his wisdom during a PHP-fig group discussion on HTTP message interfaces – for PSR-7, as well as while I attended one of his talks.

I cannot say it enough – MWOP is an awesome human being and a fantastic PHP developer.

And Now The Interview…

It all started when I saw the following tweet from MWOP:



Before we progress, I am using the following throughout the rest of this article interview:

Read TASK as “making #zf components compatible with PHP 7.2

>> Hey Matthew! For those that might not know you, can you please briefly introduce yourself and your relationship with Zend/Rogue Wave?

I am a Principal Engineer at Zend Technologies, a RogueWave Company. I’ve worked with Zend since 2005, starting first in their (then nascent) eBiz division, and then transitioning full-time to the Zend Framework team in 2007, following several successful initiatives I led on the project while working in eBiz.

In 2008, I was promoted to Software Architect, in 2009 to Project Lead, and in 2013 was promoted to Principal Engineer.

I remain project lead for Zend Framework and its associated components and sub-projects (such as Apigility and Expressive) to this day, and the upkeep and development of them is my primary job responsibility.

I also am tasked with working on the development of standards with PHP-FIG, and reviewing incoming features for the PHP language to see how they might affect how we develop the projects.

I have a small team I work with directly at RogueWave; the majority of the work I do is with outside collaborators who volunteer their efforts to the project.

>> Just so we are all clear, what are we meaning by “components”? Are these independent PHP libraries, 100% decoupled from ZF, that can be used outside the scope of any ZF-based application?

Zend Framework is a suite of components that may be used at-will and independently, or together as part of a “framework” project. (More on that later.)
These include packages such as:
  • zend-filter
  • zend-validator
  • zend-paginator
  • zend-eventmanager
  • zend-servicemanager
and so on and on.
We currently have triple-digit numbers of components we maintain.

>> What was the latest version of PHP that these components supported, prior to the move to PHP v7.2?

>> I do not have the whole picture about all things happening at ZF – are you guys working directly into compatibility with PHP v7.2 without going through 7.0, 7.1 ?

I’ll answer these two questions together, because they are related. Existing components have supported PHP versions from either 5.5, 5.6, or 7.1 and up.
For the last 2-3 years, we’ve been gradually phasing out PHP 5.5 support (as it is no longer supported by the PHP project), and, as new versions are released, ensuring that the components work predictably on those versions.
The current initiative is to make sure that all of our projects work with PHP 7.2.
A longer term initiative is that all new components will only support PHP 7.1 and up (most of the latest Expressive packages fall in this category), and new MAJOR versions of components will adopt PHP 7.1 as their minimum version.

For the task of providing PHP 7.2 compatibility, most components already do; we just haven’t provided proof via our continuous integration.

In a few cases, though, we’ve discovered we were using deprecated functionality and/or were defining signatures in class extensions that are no longer allowed starting in 7.2 (e.g., you cannot add or remove by-reference binding to arguments or a method on an extension). This latter change, becoming more strict with regards to signatures, has been particularly problematic and revealing about what both we and projects we depend on do.

In particular, PHP 7.2 became more strict with regards to how it allows extending classes to define optional parameters in methods. Prior to 7.2, you could change the default value in an extending class.

For example, if you had defined:

    public function get($name, array $options = null)

Then an extending class could override the method and define it as follows:

    public function get($name, array $options = [])

Starting in PHP 7.2, the latter gets flagged as a fatal error, instead of being silently accepted. We ran into this issue both in our own code, as well as supporting libraries such as PHPUnit. As a result, we couldn’t just add PHP 7.2 to our testing matrix; we also had to upgrade PHPUnit so we could even run the tests in the first place.
This in turn caused additional problems: PHPUnit 6 and 7 only work on PHP 7.1 and up, which means that we need to have functionality in place in our Continuous Integration system (we use Travis-CI) to switch between versions based on PHP version being tested.

>> I want to understand the process involved with the team regarding this TASK?  How are compatibility issues discovered, are each component tested for it..etc And since Zend is an enterprise, I would guess there are formal internal processes involved for even a trivial update on a component? So tell us all about it 🙂

The process is the same one we’ve used successfully for a number of years: we test against each PHP version that Travis-CI supports.

Generally, as betas and/or RCs of a new version of PHP become available on Travis-CI (generally through nightly builds), we start adding them to our Travis-CI configuration in order to identify issues, and either update our code to make it compatible, or report issues to the PHP project when we identify BC breaks.

That process has evolved a ton for us in the last few years, due to changes in PHP 7.1/7.2 and PHPUnit. We have to have mechanisms in place to vary dependencies installed based on the PHP environment being tested.

We’ve come up with a predictable and reliable strategy, but it has only stabilized in the last six months.

First, we update our PHPUnit dependency to allow any of the 5.7, 6.0, and 7.0 versions: "phpunit/phpunit": "^5.7 || ^6.0 || ^7.0".

In some components, where we haven’t had many changes, we were still supporting PHPunit 4.8, which has meant further updates (more on that later).

Next, we ALWAYS commit our composer.lock file.
This allows us to do some neat things in Travis. Speaking of: here is a sample from one of our Travis-CI configuration files:

- COMPOSER_ARGS="--no-interaction"
- COVERAGE_DEPS="php-coveralls/php-coveralls"matrix:
– php: 5.6
– DEPS=lowest
– php: 5.6
– DEPS=locked
– LEGACY_DEPS=”phpunit/phpunit”
– php: 5.6
– DEPS=latest
– php: 7
– DEPS=lowest
– php: 7
– DEPS=locked
– LEGACY_DEPS=”phpunit/phpunit”
– php: 7
– DEPS=latest
– php: 7.1
– DEPS=lowest
– php: 7.1
– DEPS=locked
– CS_CHECK=true
– php: 7.1
– DEPS=latest
– php: 7.2
– DEPS=lowest
– php: 7.2
– DEPS=locked
– php: 7.2
– DEPS=latestbefore_install:
– if [[ $TEST_COVERAGE != ‘true’ ]]; then phpenv config-rm xdebug.ini || return 0 ; fi


– travis_retry composer install $COMPOSER_ARGS –ignore-platform-reqs
– if [[ $LEGACY_DEPS != ” ]]; then travis_retry composer update $COMPOSER_ARGS –with-dependencies $LEGACY_DEPS ; fi
– if [[ $DEPS == ‘latest’ ]]; then travis_retry composer update $COMPOSER_ARGS ; fi
– if [[ $DEPS == ‘lowest’ ]]; then travis_retry composer update –prefer-lowest –prefer-stable $COMPOSER_ARGS ; fi
– if [[ $TEST_COVERAGE == ‘true’ ]]; then travis_retry composer require –dev $COMPOSER_ARGS $COVERAGE_DEPS ; fi
– stty cols 120 && composer show

– if [[ $TEST_COVERAGE == ‘true’ ]]; then composer test-coverage ; else composer test ; fi
– if [[ $CS_CHECK == ‘true’ ]]; then composer cs-check ; fi
– if [[ $TEST_COVERAGE == ‘true’ ]]; then travis_retry php vendor/bin/php-coveralls -v ; fi


Let me decipher this for you.

We define some basic details that are not environment dependent: initial composer arguments, and the dependency we will use for pushing coverage reports to the CI job that analyzes those.

Next, we define our jobs. Each job is a combination of a PHP version, and what set of dependencies (DEPS) to use, which is one of either “lowest”, “locked”, or “latest”.

Some jobs define additional environment information, such as whether to run test coverage or CS checks, or additional “legacy” dependencies.

Before we install anything, we determine if we are running test coverage; if not, we disable XDebug, which helps boost both Composer performance as well as testing. We’d prefer jobs execute quickly!

The installation phase is where it all comes together. We first install dependencies from the lock file, ignoring any platform requirements.

This allows developers to update the lock file without worrying about whether a given dependency works on all PHP versions (some packages will remove support for a major version of PHP within a minor release!).

Next, we check to see if a LEGACY_DEPS environment variable was defined; if so, we run a composer update referencing the packages it lists — this is what allows us to install an earlier version of PHPUnit (and, occasionally, other packages) on PHP 5.6 and 7.0!

Next, if DEPS is latest, we run a composer update, and, if DEPS is lowest, composer update --prefer-lowest --prefer-stable to test against the latest and earliest versions of dependencies allowed, respectively.

Finally, we list the final set of packages installed for the job.

The script includes stty 120 to set the output width; if this is not set, composer does not detect a TTY is in use, and spits out only the package names, but not the versions; the latter is very important when analyzing jobs, as it allows us to identify a potential range of dependency versions that led to test failures. (As an example, just yesterday, I discovered jobs that always passed on “lowest”, but not on “locked” or “latest”, and only with PHP 7.1+; by examining the dependencies, I was able to isolate the problem to a change in behavior in PHPUnit that I was then able to provide a change in test setup to accommodate.)

As a maintainer, I can switch to a PHP binary mimicing the setup of a failed job, install the same dependencies using the same sequence of commands the job ran, and run tests myself in order to drill down into them better (e.g., with a debugger, running individual tests, etc.).

>> Is there a pre-defined roadmap with this TASK and hence a deadline?

We defined a GitHub project for the task, but set no deadline.

The reason we set no deadline is that this was also an opportunity for us to touch basically every single component and review any existing open patches.

This process takes time, and there’s no way to meaningfully estimate it.

Some patches you review take a moment or two to understand and merge. Others take hours.

Some components have only a few open patches, if any; others have a dozen or more.

As such, we left it open-ended, but chose to make this a focus of our attention until it was complete.

>> There are 166 repositories (components), handled by 21 people. Are all these people working officially for Zend or do these include voluntary contributors as well, chosen by Zend?

No; the vast majority of these people (the community review team) are volunteers. These maintainers are most often chosen by me based on past activity, but are in some cases recommended by others on the community review team. They provide code review, merge patches, and create releases.

>> What are the main challenges that came through, either for you or the team, during this TASK?

The biggest issue was PHPUnit compatibility with PHP 7.2, and ensuring we could install and run PHPUnit on each of the target environments.

The example Travis-CI configuration I outlined above was the result of a number of iterations, and we learned from each of them… but it took time. Additionally, there are differences in the various PHPUnit versions, which meant we had to adapt existing tests. Fortunately, the PHPUnit developers tend to think about forwards compatibility, and introduce features from one or two major versions down the line to allow you to begin migrating your test suites. Some examples:

  • PHPUnit 5.6 or 5.7 added class aliases for namespaced versions of their classes, allowing developers to reference them by the namespaced versions that were released in PHPUnit 6.
  • The PHPUnit 4 series allows creating mock objects via createMock() or a combination of getMockBuilder(...)->getMock(), allowing developers to migrate to those constructs from the original getMock() method (which was deprecated in PHPUnit 5 and removed in PHPUnit 6).
  • PHPUnit 5 added the expectException*() methods, which were removed in PHPUnit 6, allowing developers to migrate to those from the original setExpectedException() implementation.

While having these is great, we found we needed to adopt all the latest features at once if we also wanted to test against PHP 7.2.

The reason is that PHPUnit versions prior to version 6 did not work with PHP 7.2 due to language features PHPUnit used that were marked deprecated in PHP 7.2 (and thus resulted in triggering PHPUnit’s internal error handler).

Generally, we are able to simply add new job entries for a new PHP version, verify they run and pass, and move on. Adding support for PHP 7.2, however, meant updating all tests and our CI processes.

>> While creating a component, what’s the deciding factor – is it because the objectives of the main project requires it, is it because someone in the team identified that such a component would be useful or is also because another framework is offering a similar one and ZF need as well to have it? (I know I’m too curious at times :D)

Many of the components we have today have their roots in Zend Framework 1, where we created them to provide a full-featured framework. These included features such as filtering, validation, pagination, sending and receiving email, database access, etc. Around 3-4 years ago, we realized that we were having trouble evolving any of these individually because their lifecycles were dependent on the framework lifecycle, and started looking at ways we could split them out. This culminated in the 2.5 release three years ago: we split all the components into their own repositories, and made the framework package a “metapackage” (a package that ships no code, but instead requires other packages).


Since then, we’ve added quite a number of new packages. Some of these are features we develop to support the greater PHP ecosystem: Diactoros, our PSR-7 implementation, was developed alongside the specification, and Stratigility provides a general-purpose middleware dispatcher (and now implements and consumes PSR-15!). With Expressive, we have created a new micro-framework for developing middleware applications, and much of our new development is around middleware packages that we feel can benefit the PSR-15 and PSR-7 ecosystems. In many cases, these packages act as _bridge_ packages: zend-expressive-authentication-oauth2, for example, bridges between our general-purpose authentication middleware and the PHP League’s oauth2-server package. 


One other thing we are working towards is splitting existing packages into more discrete functionality. As an example, zend-cache provides around a dozen adapters, most of which have dependencies on specific extensions. Our plan is to split those adapters into their own packages, leaving the main zend-cache package to primarily define interfaces, common plugins, and non-extension-based adapters such as the Memory and Filesystem adapters. This will allow the individual adapter packages to explicitly require the extensions they use, and greatly simplify and speed up testing (the zend-cache CI builds often take upwards of 20 minutes to complete currently, most of which is due to enabling and configuring extensions, and running tests for every single adapter we ship!).


Finally, we create new packages targeting new functionality when we identify a need for them. As an example, we wanted a package for reporting Problem Details for HTTP APIs (IETF RFC 7807) for our PSR-15 middleware. There were a couple of packages that would create Problem Details value objects, but none that would create PSR-7 responses, nor any error handling middleware that would do so. As such, we created zend-problem-details for these purposes. Another example was providing Hypermedia Application Language (HAL) representations. Again, we found packages for creating the value objects, but none that would create PSR-7 responses, and none that would translate between pure-PHP value objects and HAL.


More and more, however, we are looking to see if good packages exist in the ecosystem already, and directing our users to those, and, when relevant, providing documentation on how to consume those within Expressive or zend-mvc.

>> One of the tickets created for this TASK, had the title “Add PHP 7.2 support, drop HHVM”. Can you tell more about that?

We decided a year ago that not only would we require that new components and new major versions of existing components use PHP 7.1 as a minimum, but that we would stop supporting HHVM. The reasons behind this were several:


  • PHP 5.6 and up introduce features not available in HHVM or not compatible with HHVM.
  • Usage rates of HHVM are very, very small.
  • PHP 7 is really, really fast, making the primary selling point of HHVM mostly moot.
We allow dropping HHVM and/or minor versions of PHP in minor releases of our packages, and felt that, if we were already making changes to our Travis-CI configuration, this would be a good time to remove testing on that platform.

>> Each time a new (major) version of PHP will be out, the components would necessitate another update regarding compatibility. So is there a specific way that the team codes those component to ease such related TASK? How are things done to address TASK in the best possible manner each time periodically?

The PHP team has a “release train” that they stick to, and it generally involves a number of months in alpha, as changes that require API/ABI breaks from approved RFCs are added, a few months in beta as new features that do not break API/ABI are added, and a couple months in RC status, as they polish the release and identify any new bugs based on the changes.


We generally start testing against nightly builds either during the beta or RC phase, and adapt our code to work, if we can do so in a backwards compatible way, and/or report issues to the PHP project when we identify breaking changes. We try to have support available before the release drops, but, in cases where larger changes are necessary (such as the migration to PHP 7.2 and compatible versions of PHPUnit), we take the time we need to get it right, and will release later.


Adopting PHP 7 was not terribly difficult. The PHP project tries very hard to keep BC breaks to a minimum, and, generally speaking, attempts to provide guidance in how to adapt existing code such that it will work in existing versions, and become forwards compatible with the new version. In my experience, any BC breaking changes in PHP typically address language level problems: fixing signatures to remove ambiguity, making syntax more predictable, etc. Testing against a new major version helps us identify when we are using language features incorrectly, and forces us to fix our code to use the language better.

The End of monolithic framework at Zend?


>> Is ZF really now 100%-ly made up of decoupled independent components?



Three years ago, we released version 2.5, which split the framework out from a single repository into a repository per-component. From that time forward, we have developed each component on its own lifecycle. At the same time, we marked the 2.4 series as a Long Term Support release, to address:


  • Users of PHP 5.3; we dropped support for PHP 5.3 and 5.4 when we released our own version 2.5, but, at the time, we had a lot of users who were still on PHP 5.3. Giving them an LTS gave them breathing room to upgrade.
  • Users of the monolithic framework liked having a single tarball or dependency to install, and this gave them opportunity to gradually learn Composer and adapt to workflows that use.
A year after the split, we released Zend Framework 3. What was interesting about this release is that it wasn’t a single package. Instead, we shipped a skeleton application with very minimal dependencies:


  • zend-skeleton-installer, which provides prompts for optional features you may want to install, and which removes itself after initial installation.
  • zend-component-installer, which is a Composer plugin that checks to see if a component exposes itself as a ZF module (or Expressive config provider)
  • zf-development-mode, which allows you to toggle development mode
  • zend-mvc, the MVC layer itself


What’s more interesting is zend-mvc: it has a small set of dependencies, too, and acts solely as a bridge layer between those components:
  • zend-eventmanager
  • zend-http
  • zend-modulemanager
  • zend-router
  • zend-servicemanager
  • zend-view
The bulk of the effort in the v3 series was to identify and minimize dependencies in each component, to allow them to be shipped standalone. You can use zend-router in middleware applications. You can use zend-view as a template engine for any application. You can use zend-eventmanager within a Laravel, Symfony, or CakePHP application. We provide some opt-in functionality in each component to provide autowiring within a zend-mvc application (or, in many cases, an Expressive application), but you can use them on their own.


The approach is working.


With the monolithic framework, at best we released bugfixes and/or feature releases up to 20 times a year (at one point, we had a bi-weekly schedule for bugfix releases). With the change to component releases, last year alone we published 260 releases across 85 repositories, and had over 100 million downloads of all packages! This approach gets bugfixes and features to users faster, and leads to more confidence in the project.


(I’ll note that not all repositories are treated equally. Having such a large number of packages to maintain can mean some slip through the cracks, and we’ve had a number where patches have lingered for 18 months or more. As such, we’re also trying to identify packages we no longer wish to maintain, and looking for alternatives to direct our users to.)

>> I guess it took a lot & a lot of hardwork, energy and time to reach this milestone. Do you want to briefly share your experience through this?

When I tweeted the end of the monolithic framework, what’s interesting is that we have been operating under that paradigm for two years now.

The tweet simply commemorates the fact that on 31 March 2018, the ZF 2.4 LTS ended. 2.4 was the last version shipping as a monolithic framework, and the end of its LTS means we will no longer be updating it.

This simplifies things for us greatly; the LTS releases were complicated to create, and quite error-prone (due to difficulties testing the monolithic framework, lack of automated processes around updating Zend\Version, etc.).

The end of the LTS means we can focus ONLY on the components going forward. Frankly, I’m quite pleased, as it’s the culmination of several years of effort!

>> Expressive 3 provides a middleware microframework approach.

>> Would you say that a middleware approach is better than going the traditional way (MVC approach for example) that most developers are used to?
>> Is there any disadvantage of that architectural approach?
I’ll answer these two together.


MVC frameworks are nice because there’s no guesswork: they typically install _everything_ you might need for a project, whether you will use it or not. So, if you don’t need forms right away, the form support is still installed for that moment when you _do_ need to create them.


However, MVC frameworks are also generally highly opinionated about the specific workflow an application will use, even down to the level of dictating exactly where to put files, register configuration, etc. If you try and do something even slightly different, you will often find yourself hacking around the framework.


Then there’s the “magic”. In order to make the common tasks easy, most frameworks have tools for rapid application development that hide complex implementation details. These allow you to prototype features quickly and easily initially. However, if you do not take the time to learn how the “magic” works, you may find later that they limit you, or that you cannot easily change their behavior to suit your specific application.


I’ve found middleware to be an interesting and refreshing approach to complexity. It allows me to create exactly the workflows my application needs, from the macroscopic, application level, down to individual HTTP method/path combinations. If I do not need authentication everywhere, I can add it to the specific areas of my application that need it. If I want API-specific error handling, I can add it at a path level, or to specific routes.


The pitfall of middleware is that it means that you often do more work up front, more explicitly. This means more typing, and more decision making, which is often the antithesis to rapid application development. That said, I tend to favor explicit over magic, as it helps me identify complexity, and determine if I can refactor it to be simpler.


Personally, I recommend:


  • If you know the ins and outs of an MVC framework, use it. But start learning middleware, and identifying where middleware may help you better implement functionality in your project.
  • If you don’t know an MVC framework well, use middleware. It will grow with your needs.

>>In Expressive 1.X, you used a “double pass middleware” approach, whereas going forward with Expressive 3, this is no longer the case, as it now uses lambda middleware. So there must be something that was noted for that change to occur. 

>> Could you share your insight about the why behind that change and why you believe the lambda is a better approach that the double pass?
The change was due to adoption of the PSR-15 specification.


When PSR-15 began, we all expected that it would simply ratify the prevalent double-pass style. But we identified a number of problems with it.


First, using a generic `callable` for the “$next” or “$handler” argument is a terrible contract. There’s no guarantee it will accept the values passed to it, or return what is expected.


Second, passing the response to middleware is quite problematic. If middleware alters that response, but ultimately delegates to another layer (via $next/$handler), there is no guarantee that the response returned by another layer will contain the alterations; it could return a new response entirely. What we discovered was that a lot of middleware was operating on the response _prior_ to calling $next/$handler, and we were seeing lots of bugs as a result.


As such, a “best practice” was arising whereby developers were only using the $response passed to the middleware as a _prototype_ for use when they were returning a response directly. However, this also has problems. While PSR-7 classes are modelled as immutable, there is one exception: the StreamInterface. This interface is composed in request and response bodies, and is _not_ immutable, due to a language level limitation: stream resources in PHP cannot be cloned. As such, one middleware could write to the response body, but still delegate to another layer, and now there’s a potential for multiple middleware writing content, which is almost never acceptable.


So, PSR-15 went with a lambda approach. By eliminating the response from the arguments to either middleware or the handler, we prevent common mis-uses of the response object. Further, by adopting PHP 7, we are able to provide _return type hints_ on both interfaces, ensuring a strong contract for consumers.

>> Can the microframework, Expressive, be used to create a complex applications that would normally be done by the full-fledged ZendFramework?


>> It’s been a very long time I have not kept myself updated with ZendFramework. Does the v3 still uses an MVC approach or has it been revamped to provide a middleware architecture approach first?

We provide both!


Zend Framework 3 was more of an _initiative_ than a single framework version. As noted earlier, the main thrust of the work was to minimize cross-component dependencies to allow standalone usage of components.


We then shipped two separate runtimes: zend-mvc, and Expressive. zend-mvc is identical to ZF2 (with a few changes and feature additions), while Expressive provides a middleware microframework. If you are familiar with ZF2, migrating to ZF3 will pose no problems for you. (The main changes are BC-breaking changes to zend-servicemanager and zend-eventmanager, and we provide a lot of tooling and documentation to make the transition as easy as possible.) 


One new feature of interest, however, is that zend-mvc now ships an optional MiddlewareListener, allowing you to route to middleware (and middleware pipelines!) within your zend-mvc application.


>> I know this would sound a bit like comparing apple to oranges, but what is Zend trying to achieve (differently) using either of Zendframework or Expressive, when compared to either of Symfony or Laravel? Why would someone choose ZF over its mentioned competitors?

Our primary mission is to provide general purpose components that you can use in any application.


We secondarily provide runtimes (zend-mvc and Expressive) that integrate these components (as well as those outside our ecosystem), and specifically recommend PSR-15 middleware architectures as a general-purpose approach to developing web-facing PHP applications.


We feel that you can and should choose Zend Framework components where they fit your development needs, regardless of the framework you use. It’s not a zero-sum game, particularly in a Composer-enabled ecosystem.

>> Matthew, I thank you enormously for your precious time with 7PHP. I know and understand you have a very busy schedule. I’m very thankful and grateful to you. A last word before we close up?

I’m very proud about the changes we’ve made in the Zend Framework ecosystem in the last few years.
We have gone to great lengths to make ZF relevant in a world where users can literally build their application out of any packages Composer can install, without regard for framework.
I think our switch towards middleware ecosystems is a forward-thinking step for the PHP ecosystem. Ultimately, I look forward to the day that developers choose middleware packages from anywhere that suit their needs, and push them into a middleware dispatcher they have selected or developed to address their specific application needs.
Frameworks are great; framework silos, not so much. We’re all PHP developers; let’s work together to build amazing and useful products for the world.

3 Comment(s)

  1. Great interview! Helped me a lot on how to direct the use of Zend for the next few days. I recently started a Zend Expressive-based project, but was not sure if I ‘d be better using Zend MVC.
    The answer “Absolutely” about if Expressive would fit complex applications, really saved my day!
    Thanks for great interview!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.