PHP: Hypertext PreprocessorPHP 7.4.0RC4 Released! (18.10.2019, 00:00 UTC)
The PHP team is glad to announce the fourth release candidate of PHP 7.4: PHP 7.4.0RC4. This continues the PHP 7.4 release cycle, the rough outline of which is specified in the PHP Wiki. Please DO NOT use this version in production, it is an early test version. For source downloads of PHP 7.4.0RC4 please visit the download page. Please carefully test this version and report any issues found in the bug reporting system. 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. These files can also be found in the release archive. The next release would be 7.4.0RC5, planned for October 31st. The signatures for the release can be found in the manifest or on the QA site. Thank you for helping us make PHP better.
Matthew Weier O'PhinneyAn Apology to php[world] Attendees (17.10.2019, 18:30 UTC)

Due to disorganization on my part, I accidentally booked php[world] 2019 to coincide with a family commitment.

After reviewing a variety of options, I let the organizers know last week that I could no longer attend. It's a situation I hate, because there's nobody to blame but me, and no matter what option I could come up with, somebody would end up disappointed or inconvenienced. For my part, my family had to come first.

Fortunately, the organizers at php[world] were able to convince Ryan Weaver to fill in for me on the PHP and Frameworks panel, and to deliver a talk to replace my slot in the program. I'm happy that he was able to step in!

I hope everyone attending the conference has a great experience! Next time, I'll plan better!

mwopAn Apology to php[world] Attendees was originally published on by .
Derick RethansPHP Internals News: Episode 32: Writing Extensions (17.10.2019, 08:32 UTC)

PHP Internals News: Episode 32: Writing Extensions

In this episode of "PHP Internals News" I chat with James Titcumb (Twitter, GitHub, Website, LinkedIn) about writing PHP extensions commercially.

The RSS feed for this podcast is, you can download this episode's MP3 file, and it's available on Spotify and iTunes. There is a dedicated website:


Music: Chipper Doodle v2 — Kevin MacLeod ( — Creative Commons: By Attribution 3.0

Become a Patron!
Rob AllenCustom error rendering in Slim 4 (16.10.2019, 10:00 UTC)

One of the nice things about Slim 4 is that it's easier to customise the HTML generated on error without having to worry about the rest of the error handling mechanism. This is because we have separated error rendering from error handling.

Slim's default ErrorHandler maintains a list of renderers, one for each content-type and will delegate the creation of the error payload (HTML, JSON, XML, etc) to the renderer. Out of the Box, the error hander registers an HtmlErrorRenderer which provides a very basic error display:

Slim4 default error no details

We can also enable the displayErrorDetails setting to view the information about the error:

Slim4 default error with details

Separately, the error handler can log these details to the error log.

Writing a custom HTML renderer

To write a new error renderer, we need to create a classs that implements SLim\Interfaces\ErrorRendererInterface. This interface requires a single method:

public function __invoke(Throwable $exception, bool $displayErrorDetails): string;

We are given the exception that caused this error and have to return the HTML we wish to be displayed.

Let's create our own HTML error renderer. If you want to play along, my Slim4-Starter project is a good place to start from.

We start with a basic HtmlErrorRenderer, which we'll store in the src/Error/Renderer directory:



namespace App\Error\Renderer;

use Slim\Exception\HttpNotFoundException;
use Slim\Interfaces\ErrorRendererInterface;
use Throwable;

final class HtmlErrorRenderer extends ErrorRendererInterface
    public function __invoke(Throwable $exception, bool $displayErrorDetails): string
        $title = 'Error';
        $message = 'An error has occurred.';

        if ($exception instanceof HttpNotFoundException) {
            $title = 'Page not found';
            $message = 'This page could not be found.';

        return $this->renderHtmlPage($title, $message);

    public function renderHtmlPage(string $title = '', string $message = ''): string
        $title = htmlentities($title, ENT_COMPAT|ENT_HTML5, 'utf-8');
        $message = htmlentities($message, ENT_COMPAT|ENT_HTML5, 'utf-8');

        return <<<EOT
<!DOCTYPE html>
  <title>$title - My website</title>
  <link rel="stylesheet"

We can do whatever we like in __invoke(). In this case, I have chosen to change the title and message based on the class of the $exception. Slim will show a HttpNotFoundException when the router cannot find a registered route for the request URL, so we can use this to show different text explaining the problem.

We also need to render the HTML itself. This is likely to match the rest of your website's design, so the implementation of renderHtmlPage() is entirely up to you. I'm sure you can do better than I can though!

Register our renderer

We register our renderer, at the point we add the ErrorMiddleare, which in my case is in config/middleware.php:

$displayErrorDetails = (bool)($_ENV['DEBUG'] ?? false);
    $errorMiddleware = $app->addErrorMiddleware($displayErrorDetails, true, true);
    $errorHandler = $errorMiddleware->getDefaultErrorHandler();
    $errorHandler->registerErrorRenderer('text/html', HtmlErrorRenderer::class);

Don't forget to add use App\Error\Renderer\HtmlErrorRenderer; at the top of the file and now the new error renderer will now be used.

This is what our new error page looks like:

Slim4 new error page

Using Whoops for development

When we're developing, it would be useful to have more information about what's gone wrong. The whoops error handler can provide this, so let's add it. Fortunately for us, the hard work has been done already by Zeusis in their zeuxisoo/slim-whoops

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

Derick RethansPHP Internals News: Episode 31: DOM Living Standard API (10.10.2019, 08:31 UTC)

PHP Internals News: Episode 31: DOM Living Standard API

In this episode of "PHP Internals News" I chat with Benjamin Eberlei (Twitter, GitHub, Website) about an RFC that he produced that would implement the new "DOM Living Standard API".

The RSS feed for this podcast is, you can download this episode's MP3 file, and it's available on Spotify and iTunes. There is a dedicated website:

Show Notes


Music: Chipper Doodle v2 — Kevin MacLeod ( — Creative Commons: By Attribution 3.0

Become a Patron!
Derick RethansXdebug Update: September 2019 (8.10.2019, 08:25 UTC)

Xdebug Update: September 2019

Another month, another monthly update where I explain what happened with Xdebug development in this past month. It will be published on the first Tuesday after the 5th of each month. Patreon supporters will get it earlier, on the first of each month. You can become a patron here to support my work on Xdebug. More supporters, means that I can dedicate more of my time to improving Xdebug.

In September, I worked on Xdebug for about 30 hours, on the following things:

Bug fixes

I alluded in last month's report that there were still a few bugs to fix before I can release Xdebug 2.8.0 RC1. I have now fixed the main outstanding one that had to do with garbage collection. Additionally, I addressed two issues related to external extensions that do things in a "boutique" way (phalcon and ionCube). I am expecting that the RC1 release will come in the middle of October.

Xdebug 3 development

I started with the development of Xdebug 3, and more specifically, refactoring its different features into their own separate modules. Xdebug's main features (code coverage, debugger, profiler, function tracing) all now live in their own separate directory. At the moment I am refactoring the initialisations of each of the functions so that each "module" is responsible for its own initialisation, instead of everything being done in one big function for PHP's 5 life cycle events (process start/stop, request start/stop/post stop). This work is still ongoing, and not going to be ready for quite some time.

Some of the tedious work—moving the test files into their respective module's directory—has been finished, but there remains plenty to do. My first milestone is reorganising all the code so that it is easy to see where things can be improved. I suspect that will take at least until December.


When I set-up my Patreon tiers I included "this tier will also give you access to podcasts and videos showing upcoming Xdebug features or coding/problem solving sessions" with the Cricket tier and higher. I have now started creating screen casts of my Xdebug 3 work, and made them available to the Cricket and higher tiers. The first one is also available on Vimeo. I plan to release these screen casts through Patreon continuously, and also make some of them available for non patrons on Vimeo in the future. In the near future, I would also like to experiment by doing live session through Twitch.

I have embedded the first one here too:

Ep 001 — Breaking up the globals

Once Xdebug 3 gets to a usable state and I've redone settings and functionality, I will also be producing tutorials and training sessions.

A Business Supporter Scheme

Although I have been going on about Patreon for half a year now, it isn't really quite a solution for companies that want to help out. Patreon doesn't really do invoices correctly, which might be required for a company to be able to help to fund my work on Xdebug. Patreon is also mostly focussed on individual developers, and being able to get "perks", which also doesn't really match with the needs of companies.

With that in mind, I have launched a Business Supporter Scheme.

To differentiate this from the "Open Source side", I've decided that I will only do community support through Stack Overflow. And henceforth I will close down my support mailing list—it gets hardly any traffic anyway. Pro and Business subscribers

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

Evert PotStructured headers NPM package: new version (4.10.2019, 13:00 UTC)

I just updated my structured-headers package to be up to date with the latest verison of the Structured headers IETF draft.

If you do anything with HTTP, structured headers might be something you have to deal with in the future.

Many HTTP headers encode complex values, and many HTTP headers have their own serialization format.

In an effort to reduce this, the Structured Headers specification is being written, which introduced a standard HTTP header format to serialize many types of data, such as numbers, string, lists, objects, parameters, booleans, etc.

It’s very likely that many new HTTP headers that are being standardized in the future will all follow the new structured headers format.

It’s a bit risky to adopt before it’s a full standard, as the format has changed a lot over its development. However, as soon as it stabilized it will be an excellent choice as an encoding mechanism for your own custom headers as well.

Stefan KoopmanschapPHP and the DigitalOcean MySQL cluster (4.10.2019, 11:34 UTC)

One of the weak points in our Rancher 1 cluster has always been the database. Because databases and docker (due to the persistence issues) has always been an issue, we solved that by installing a MySQL server on the same droplet that our Rancher server was running on. While it worked fine, it was always a bit of a weak spot: If that single MySQL server would crash, all our applications would go down. And since we work mostly on customer projects and don't have a dedicated ops person, we wouldn't always been able to immediately respond to such a crisis.

So when DigitalOcean announced their managed MySQL cluster, I was quickly excited about this new project. It took a while for them to launch it publicly and roll it out to "our" region (AMS3), but they did so just over a month ago, so I decided to go for a testdrive.

Creating my first database

Creating a database wasn't all that hard. DigitalOcean has an interface for this. It is literally filling in your database name and clicking a button to set up your database. The same goes for creating a user. This interface is quite limited though: You can not input any configurations (such as the authentication method for users), which can cause issues (as you will later see). But in all its simplicity, it does what it is supposed to do. Create a database. Create a user.

Migrating the database

Migrating the database was actually quite easy. Dump the database from the old MySQL server, import it on the new server. I used MySQL Workbench to do this, and that worked fine.

Mind you: The first application I did this one had a very simple schema. DigitalOcean managed MySQL uses MySQL 8, so in more complex databases I can imagine there might be issues due to backwards compatibility breaks. YMMV.

Configuring my application

I had a very simple issue to solve on my application: My configuration did not allow me to set the port for the DSN, and since DigitalOcean sets a custom MySQL port, this meant I had to make a very simple code change so I could configure the port that was used. A simple one line change solved that issue. No problem so far.

When I deployed a new version of my application with this fix however, I ran into a bigger issue:

Fatal error: Uncaught PDOException: PDO::__construct(): The server requested authentication method unknown to the client [caching_sha2_password] in /var/www/web/index.php

Oops! Yes, MySQL now defaults to a new authentication method, caching_sha2_password. This is not supported by PHP yet.

This is where I come back to my earlier mention of how the simplistic user management of DigitalOcean is causing problems: We can't switch to another authentication method! Fortunately, we can execute a query to actually switch back to the old authentication method. So let's do that:

ALTER USER 'myuser'@'%' IDENTIFIED WITH mysql_native_password BY 's3cr3t_p@ssw0rd';

After doing this, my application worked again. Yay, my application is now running on the new managed MySQL cluster!

About caching_sha2_password

Jaap and I did some digging to figure out why this new MySQL 8 authentication method is not yet supported by PHP. Because really, MySQL is the main database engine used by PHP developers, so why would it not be supported? It turns out, it was! If you use PHP 7.2.9 (at least the docker image for that), you can actually use the new caching_sha2_password method. Your application works fine. However, after that change, a bug was reported after which the support for the new authentication method was reverted. As it looks right now, the changes for the authentication method are back in the master branch, which would mean PHP 8 will support the new authentication method. Until then, we'll have to switch back to mysql_native_password for our PHP applications (or use the PHP 7.2.9 docker image, which I would advice against).

The verdict

Migrating to the new database cluster was easier than I expected and, with one minor work-around, it is easy to get your application up and running with the new DigitalOcean MySQL cluster. We will surely be migrating all application to this new platform. It's up to DigitalOcean to extend their application a bit more, for instance to be able to configure the authentication method for a user or default character set of the database. So far, I'm a happy user of this new DigitalOcean product.

Disclaimer: This is not a sponsored post. I am not affiliated with DigitalOcean other than that I am a happy customer.

Matthew Weier O'PhinneyLooking For A New Adventure (3.10.2019, 20:44 UTC)


As of 2019-10-01, I am once again employed full-time. Thank you everyone who reached out!

Fourteen years ago, almost to the day, I received a job offer from Zend to join their nascent eBiz team, where I started contributing almost immediately to the yet-to-be-announced Zend Framework. Two years later, I joined the Zend Framework team full-time. A year later, I was promoted to Architect. A year after that, I was promoted to Project Lead of Zend Framework, a role I kept for the next ten years. Over the years, Zend was acquired by RogueWave Software, which was in turn acquired by Perforce earlier this year.

Two months ago, almost to the day, was my last day with Zend/RogueWave/Perforce.

I'm now looking for a new adventure.

But first, a word about Laminas

As some of you might recall, in April, I blogged about transitioning Zend Framework to the Linux Foundation, as the new "Laminas Project".

This is still a work in progress, and I'm still dedicated to finalizing the transition. While we are well under-way technically, we're still identifying our initial corporate members. Regardless, we plan to launch the technical project soon, and will likely do a small, targeted fundraising effort to allow us to do some marketing projects and conference/speaker sponsorships while we finalize our long-term funding goals.

It's simply taking longer than we anticipated.

In the interim, I am still acting as project lead for the Laminas Project, including Apigility and Expressive, and working actively towards the project's organizational and funding goals.

And now this

Could your business benefit from somebody who has been in a leadership position of a large, enterprise, Open Source framework with hundreds of millions of downloads?

Do you need an expert PHP developer and application architect?

Do you need somebody to guide and implement your organization's API strategy?

Do you need somebody who can help you extract, maintain, and publish discrete library packages for your applications?

Do you need a competent and professional communicator for your development team?

Do you need somebody who can help you with your unit testing and continuous integration?

Do you need somebody who can implement git workflows, and help your team adopt them?

Do you need somebody to mentor your developers, teaching them about standards, object oriented programming, unit testing, and best practices?

These are all skills I can bring to the table.

What are my needs in a new position?

I work remotely. My entire tenure with Zend was done remotely, and I thrive best when I can manage my own time, including when and how interruptions occur. Additionally, I still have a child in the public school system, and uprooting them from their peers and support system is something I'd prefer to avoid. I will consider relocating, but only for exceptional teams and locations.

I would love for a company to hire me to continue working on Laminas as my primary duties. The project needs people with dedicated time to review issues and feature requests, create releases, write documentation, and answer questions from users.

One dream I've had for some time is to work for a company with a social mission, as I'd like to use my skills to make the world a better place.

mwopLooking For A New Adventure was originally published on by .
Voices of the ElePHPantInterview with Larry Garfield (3.10.2019, 18:34 UTC)
LinksRSS 0.92   RDF 1.
Atom Feed   100% Popoon
PHP5 powered   PEAR
ButtonsPlanet PHP   Planet PHP
Planet PHP