Matthew Weier O'PhinneyThe Future of Zend Framework (18.10.2018, 18:20 UTC)

For the past thirteen years, I've been either consuming Zend Framework or directly contributing to it. Since 2009, I've operated as project lead, and, since then, shepherded the version 2 and 3 releases, added Apigility to the ZF ecosystem, and helped bring middleware paradigms to the mainstream by assisting with the creation of Stratigility and coordination of the Expressive project. As I write this, the various ZF packages have been downloaded over 300 MILLION times, with 200 million of those being in the past 18 months!

In the last three years, I have performed this work under the umbrella of Rogue Wave Software, who acquired Zend in 2015. However, Rogue Wave has recently made a strategic decision to focus its efforts on the Zend Server product of the Zend portfolio. Consequently, this means both myself and Enrico Zimuel will be leaving the company and looking for new opportunities in the not-too-distant future, along with Zeev Suraski and Dmitry Stogov.

We all care deeply about the Zend Framework ecosystem, and we are evaluating options to ensure its continuation and longevity. These include either finding a new corporate sponsor for the project, or forming a foundation. This is where YOU come in: if you work for a company that would be interested in supporting such efforts, I would love to hear from you. Feel free to reach out to me at with questions or queries.

mwopThe Future of Zend Framework was originally published 17 October 2018 on by .
Zeev SuraskiThe Future of the Zend Engine and the Zend Framework (17.10.2018, 14:56 UTC)
In the past 20 years, I've been at the forefront of the development of the Zend Engine - the 'kernel' of PHP - both personally and via my team.  We led many of the key advancements in the language runtime, including most recently the development of the updated brain that made the wonder that is PHP 7 - and many other things over the years.  We're very proud of these contributions, and I believe they had a critical impact in both the rapid proliferation of PHP in the past - and for keeping it competitive in recent years.  Other folks in my team have led the development of other prominent components in the PHP ecosystem - namely Zend Framework, Apigility and Zend Expressive - which too are being used by hundreds of thousands of companies.

In the last three years - after Zend was acquired - we continued to do this work under the umbrella of Rogue Wave software, for which I'm very thankful.  However, Rogue Wave has recently taken a strategic decision to focus its efforts on the Zend Server part of the Zend portfolio.  Consequently, I'm announcing that my team and I - including Dmitry Stogov, Matthew Weier O'Phinney and Enrico Zimuel will be leaving the company and looking for new opportunities.  This isn't going to happen immediately, but the decision has been taken.

As all of us still care very much both about PHP as well as the Zend Framework ecosystem, one of the options we're evaluating is finding a new home for these contributions, to keep both our planned contributions to PHP 8 and beyond on track, and the ongoing development of ZF and Zend Expressive thriving.  One of the reasons for this announcement - which is coming well ahead of our actual departure date - is to explore this possibility.

If you work for a company that you believe be interested in supporting such an effort, I'd love to hear from you at

Matthew Weier O'PhinneyAsync Expressive with Swoole (17.10.2018, 13:30 UTC)

Have you used Node.js?

For those of my readers unfamiliar with Node.js, it's a server-side JavaScript framework that provides the ability to create, among other things, network services. To do so, it provides an event loop, which allows for such things as asynchronous processing.

In the PHP ecosystem, a group of Chinese developers have been creating an extension that provides many of the same capabilities as Node.js. This extension, called Swoole, allows you to create web servers with asynchronous capabilities. In many cases, the asynchronous capabilities are handled via coroutines, allowing you to write normal, synchronous code that still benefits from the asynchronous nature of the system event loop, allowing your server to continue responding to new requests as they come in!

We've been gradually adding and refining our Swoole support in Expressive, and recently issued a stable release that will work with any PSR-15 request handler. In this post, I'll enumerate what I feel are the reasons for considering Swoole when deploying your PHP middleware application.

I feel there are three key advantages to Swoole, and, by extension, any async PHP runtime:

  • Application-specific servers
  • Performance
  • Async processing

Application-specific servers

There are a few general architectures for applications:

  • A single web server sitting in front of many web applications.
  • A single web server sitting in front of a single web application.
  • A load balancer sitting in front of many servers. Some servers might serve the same application, to provide redundancy. (Often, today, these may even be identical docker containers.)

nginx serving many PHP sites

The first scenario is common in internal networks and development, and in many shared hosting scenarios. It's generally considered less secure, however, as a vulnerability in one application can potentially escalate to affect all applications hosted on the server. Additionally, it means that any updates to PHP versions must be tested on all applications, which often means updates are few and far between — which is also problematic from a security standpoint.

When you want to isolate the environment, you'll move to a single web server, single PHP application model:

nginx serving a single PHP site

And when you start scaling, this becomes a load balancer sitting in front of many of these web server/PHP application pairs:

A load balancer in front of many nginx+php sites

In each of these last two scenarios, there's one thing I want to point out: your application consists of at least two distinct services: the PHP processes, and a web server.

You may have other services as well, such as an RDBMS or document database, cache, search, etc. But generally these are on separate servers and scaled separately. As such, they're outside of this discussion.

In these scenarios, this means each "server" is actually a composite. And when you are adding redundancy to your architecture, this adds significant complexity. It's one more process on each and every node that can fail, and additional configuration you need when deploying.

When we start thinking about microservices, this becomes more problematic. Microservices should be quick and easy to deploy; one service per container is both typical and desired.

What Swoole lets us do is remove one layer of that complexity.

A load balancer in front of php servers

We can have a service per container, and that container can be built with only PHP. We start the Swoole HTTP server, and it's ready to go. We then tell the reverse proxy or load balancer how to route to it, and we're done.

This is useful in each of the scenarios, including the one web server/mulitiple applications scenario, as we can have different PHP runtimes per application. Our "web server" becomes a reverse proxy instead.

Application-specific servers allow us to simplify our deployment, and ship microservices quickly.


Remember when PHP 7 came out, and it was like doubling the performance of your application?

What if you could do that again?

In our initial benchmarks of Expressive applications, we found that they performed four times better under Swoole th

Truncated by Planet PHP, read more at the original (another 6968 bytes)

Rob AllenReplacing a built-in PHP function when testing a component (17.10.2018, 10:02 UTC)

Recently I needed to test part of Slim that uses the built-in PHP functions header() and headers_sent(). To do this, I took advantage of PHP's namespace resolution rules where it will find a function within the same namespace first before finding one with the same name in the global namespace. The idea of how to do this came courtesy of Matthew Weier O'Phinney where this approach is used for similar testing in Zend-Diactoros.

This is the relevant part of the code I want to test:

namespace Slim;

// use statements...

class App
    // ...

    public function respond(ResponseInterface $response)
        // Send response
        if (!headers_sent()) {
            // Headers
            foreach ($response->getHeaders() as $name => $values) {
                $first = stripos($name, 'Set-Cookie') === 0 ? false : true;
                foreach ($values as $value) {
                    header(sprintf('%s: %s', $name, $value), $first);
                    $first = false;

        // method continues

     // ...

This is the relevant test (simplified):

namespace Slim\Tests;

// use statements...

class AppTest extends PHPUnit_Framework_TestCase
    // ...

    public function testResponseReplacesPreviouslySetHeaders()
        $app = new App();

        $response = new Response();
        $response = $response->withHeader('X-Foo', 'baz1')
                ->withAddedHeader('X-Foo', 'baz2');


        $expectedStack = [
            ['header' => 'X-Foo: baz1', 'replace' => true, 'status_code' => null],
            ['header' => 'X-Foo: baz2', 'replace' => false, 'status_code' => null],

        $this->assertSame($expectedStack, HeaderStackTestAsset::$headers);

    // ...

This code sets up a Response object with two X-Foo headers, it then calls respond() and tests that there were two calls to header() with the replace parameter set to true only for the first one.

For this to work, we need to override PHP's header() and replace it with our own that stores the parameters into an array within the HeaderStackTestAsset class.

This is done by creating our own HeaderStackTestAsset class along with headers_sent() & header() functions that are called rather than PHP's:

// test/Assets/HeaderFunctions.php

namespace Slim\Tests\Assets {

    class HeaderStackTestAsset
        public static $headers = [];

namespace Slim {

    function headers_sent()
        return false;

    function header($header, $replace = true, $statusCode = null)
        \Slim\Tests\Assets\HeaderStackTestAsset::$headers[] = [
            'header' => $header,
            'replace' => $replace,
            'status_code' => $statusCode,

The HeaderStackTestAsset class is trivial and exists entirely as a holder for our $headers array.

We then define our headers_sent() function to always return false and then header() is set up to store the function parameters to the HeaderStackTestAsset::$headers array.

The key thing here is that the headers_sent() & header() functions are in the Slim namespace. As App is also in the same namespace, when header() is called within respond(), our version is invoked and so we can ensure that Slim does the right thing with the $replace parameter.

This is a very handy trick when you need it and works for any PHP function that's called in the global namespace (as long as the file doesn't explicitly import it using use).

Evert Pot305 Use Proxy (16.10.2018, 15:00 UTC)

305 Use Proxy is a deprecated status code. Using the status-code a server could instruct a client that it should connect to a proxy, and repeat that same request there.

305 kind of works like a redirect. It really tells a client: this resource can only be fetched if you used the right proxy. Presumably a client could connect to this proxy and via the proxy try the exact same request again to get the real response.

305 Use Proxy is deprecated due to security concerns. It shouldn’t be used. I’m not aware of any implementors, although they might be out there.


The following response would tell a client that it should attempt the same request again via a proxy on

HTTP/1.1 305 Use Proxy


Evert PotKetting 2.3 release (11.10.2018, 16:00 UTC)

I just released Ketting 2.3, the missing HATEOAS client for Javascript.

I last blogged about this project in June, so I thought it was worth listing the most interesting recent changes.

Content-Type and Accept header improvements

In the past, the Ketting library used a configurable set of mime-types for the Accept header, and some heuristics for the Content-Type headers. This has been greatly improved.

If you’re following links in this format:

  "_links": {
    "next": { "href": "/next-hop", "type": "application/vnd.some-vendor+json"}

<link rel="next" href="/next-hop" type="application/vnd.some-vendor+json" />

HTTP/1.1 200 OK
Link: </next-hop>; rel="next" type="application/vnd.some-vendor+json"

In each of those cases, the link embeds a hint for the content-type at this new location.

When running the following on a resource, the GET request will now automatically use that value fo the Accept header:

const resource = "..."; // Pretend this is a Ketting resource.
const nextResource = await resource.follow('next');

console.log(await nextResource.get()); // Will get a application/vnd.some-vendor+json Accept header.

Support for OAuth2 client_credentials grant

The library supported some OAuth2, specifically:

  • Simply supplying a Bearer token.
  • Using the password grant_type.

Now, the library also supports the client_credentials grant. The library now also detects if no refresh_token was given, and will automatically re-authenticate using the original grant_type, if this was the case.

No longer ships with a fetch() polyfill

When using the web-packed file, I noticed that a large part of the size of the Ketting library was attributable to a polyfill for the Fetch API.

Every modern browser ships the Fetch API, so this no longer seemed needed. If you do need to run Ketting on an older browser, you can simply provide your own polyfill, such as the whatwg-fetch package.


For well-behaved servers, these changes should not have a negative impact. Don’t forget to test.

To update, this should usually do it:

npm install ketting@2.3.0

Brandon SavageAvoiding Setter Injection (11.10.2018, 13:00 UTC)

PHP more or less has two kinds of dependency injection available: constructor injection, and setter injection. Constructor injection is the process of injecting dependencies through the constructor arguments, like so: The dependencies are injected via the constructor, on object creation, and the object has them from the very beginning. Setter injection is different; instead of […]

The post Avoiding Setter Injection appeared first on

PHP: Hypertext PreprocessorPHP 7.1.23 Released (11.10.2018, 00:00 UTC)
The PHP development team announces the immediate availability of PHP 7.1.23. This is a bugfix release.All PHP 7.1 users are encouraged to upgrade to this version.For source downloads of PHP 7.1.23 please visit our downloads page, Windows source and binaries can be found on The list of changes is recorded in the ChangeLog.
PHP: Hypertext PreprocessorPHP 7.3.0RC3 Released (11.10.2018, 00:00 UTC)
The PHP team is glad to announce the next PHP 7.3.0 pre-release, PHP 7.3.0RC3. The rough outline of the PHP 7.3 release cycle is specified in the PHP Wiki. For source downloads of PHP 7.3.0RC3 please visit the download page. Windows sources and binaries can be found on Please carefully test this version and report any issues found in the bug reporting system. THIS IS A DEVELOPMENT PREVIEW - DO NOT USE IT IN PRODUCTION! For more information on the new features and other changes, you can read the NEWS file, or the UPGRADING file for a complete list of upgrading notes. Internal changes are listed in the UPGRADING.INTERNALS file. These files can also be found in the release archive. The next release would be RC4, planned for October 25th. The signatures for the release can be found in the manifest or on the QA site. Thank you for helping us make PHP better.
PHP: Hypertext PreprocessorPHP 7.2.11 Released (11.10.2018, 00:00 UTC)
The PHP development team announces the immediate availability of PHP 7.2.11. This is a bugfix release.All PHP 7.2 users are encouraged to upgrade to this version.For source downloads of PHP 7.2.11 please visit our downloads page, Windows source and binaries can be found on The list of changes is recorded in the ChangeLog.
LinksRSS 0.92   RDF 1.
Atom Feed   100% Popoon
PHP5 powered   PEAR
ButtonsPlanet PHP   Planet PHP
Planet PHP