PHP Internals News: Episode 51: Object Ergonomics – Derick Rethans

PHP Internals News: Episode 51: Object Ergonomics

In this episode of “PHP Internals News” I talk with Larry Garfield (Twitter, Website, GitHub) about a blog post that he was written related to PHP’s Object Ergonomics.

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:


Derick Rethans 0:16

Hi, I’m Derick. And this is PHP internals news, a weekly podcast dedicated to demystifying the development of the PHP language. This is Episode 51. Today I’m talking with Larry Garfield, not about an RFC for once, but about a blog post that he’s written called Object Ergonomics. Larry, would you please introduce yourself?

Larry Garfield 0:38

Hello World. My name is Larry Garfield, also Crell, CRELL, on various social medias. I work at in developer relations. We’re a continuous deployment cloud hosting company. I’ve been writing PHP for 21 years and been a active gadfly and nudge for at least 15 of those.

Derick Rethans 1:01

In the last couple of months, we have seen quite a lot of smaller RFCs about all kinds of little features here and there, to do with making the object oriented model of PHP a little bit better. I reckon this is also the nudge behind you writing a slightly longer blog post titled “Improving PHP object ergonomics”.

Larry Garfield 1:26

If by slightly longer you mean 14 pages? Yes.

Derick Rethans 1:29

Yes, exactly. Yeah, it took me a while to read through. What made you write this document?

Larry Garfield 1:34

As you said, there’s been a lot of discussion around improving PHP’s general user experience of working with objects in PHP. Where there’s definitely room for improvement, no question. And I found a lot of these to be useful in their own right, but also very narrow and narrow in ways that solve the immediate problem but could get in the way of solving larger problems later on down the line. So I went into this with an attitude of: Okay, we can kind of piecemeal and attack certain parts of the problem space. Or we can take a step back and look at the big picture and say: Alright, here’s all the pain points we have. What can we do that would solve not just this one pain point. But let us solve multiple pain points with a single change? Or these two changes together solve this other pain point as well. Or, you know, how can we do this in a way that is not going to interfere with later development that we’ve talked about. We know we want to do, but isn’t been done yet. So how do we not paint ourselves into a corner by thinking too narrow?

Derick Rethans 2:41

It’s a curious thing, because a more narrow RFC is likely easier to get accepted, because it doesn’t pull in a whole set of other problems as well. But of course, as you say, if the whole idea hasn’t been thought through, then some of these things might not actually end up being beneficial. Because it can be combined with some other things to directly address the problems that we’re trying to solve, right?

Larry Garfield 3:07

Yeah, it comes down to what are the smallest changes we can make that taken together have the largest impact. That kind of broad picture thinking is something that is hard to do in PHP, just given the way it’s structured. So I took a stab at that.

Derick Rethans 3:21

What are the main problems that we should address?

Larry Garf

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

Creating a simple link registry – Matthias Noback

The problem: if you publish any document as PDF, in print, etc. and the text contains URLs, there is a chance that one day those URLs won’t work anymore.
There’s nothing to do about that, it happens.

Luckily, this is a solved problem.
The solution is to link to a stable and trustworthy website, that is, one that you maintain and host (of course, you’re trustworthy!).
Then in the document you link to that website, and the website redirects visitors to the actual location.

An example: my book contains a link to
When I moved that repository to a new organization on GitHub, this link resulted in a 404 Page not found error.
The proper URL is now
Chris from Gitstore was able to save the day by setting up a redirect on their site, but I wanted to make sure this kind of problem would never be a problem for me again.

The ingredients for the solution:

  • A domain name (I registered
  • A simple website that can redirect visitors to the actual locations

I wanted to hook this new website into my existing Docker-based setup which uses Traefik to forward traffic to the right container based on labels.
It turns out, with a simple Nginx image and some custom setup we can easily set up a website that is able to redirecting visitors.

The Dockerfile for such an image:

FROM nginx:stable-alpine
COPY default.conf /etc/nginx/conf.d/default.conf

Where default.conf looks like this:

server { listen 80 default_server; index index.html; root /srv; error_page 404 /404.html; rewrite /repository redirect;

This already works, and when I deploying the resulting image to the server that receives traffic for, a request for /repository will indeed redirect a visitor to using a temporary redirect.

Generating the Nginx configuration from a text file

When I’m working on my book, I don’t want to manually update a server configuration file every time I’m adding a URL.
Instead, I’d like to work with a simple text file.
Let’s name this file forwards.txt:


And then I want the Docker image build process to add rewrite rules automatically,
So I wrote a little PHP script that does this runs during the build.
Here’s what the Dockerfile looks like.
It uses a multi-stage build:

FROM php:7.4-alpine as php
# This will copy build.php from the build context to the image
COPY . .
# This will generate default.conf based on template.conf
RUN php build.php FROM nginx:stable-alpine
# Copy the default.conf from the php image to the nginx image
COPY --from=php default.conf /etc/nginx/conf.d/default.conf

Here’s what happens inside the PHP script:

function insertRewritesInNginxConf(string $conf): string
{ $rewrites = []; foreach (file('forwards.txt') as $line) { $line = trim($line); if (empty($line)) { continue; } $rewrites[] = ' ' . 'rewrite ' . $line . ' redirect;'; } return str_replace( '%INSERT_URL_REWRITES_HERE%', implode("\n", $rewrites), $conf );
} /* * Generate the Nginx configuration which includes all the actual * redirect instructions */
file_put_contents( 'default.conf', insertRewritesInNginxConf(file_get_contents('template.conf'))

We should add a bit of validation for the data from the forwards.txt file so we don’t end up with a broken Nginx configuration, but otherwise, this works just fine.

I don’t want to manually check that all the links that are inside the “link registry” still work.
Instead, I’d like to use Oh Dear for that, which does uptime monitoring and checks for broken links as well.

For this purpose I added another function to the PHP script, which, based

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

Making bugs ex-bugs with Xdebug –

Xdebug is an indispensable tool for every PHP developer. PHP’s favorite real-time debugger, it supports breakpoints, more detailed debug output, and deeper introspection of PHP code to determine just what it’s doing (and what it’s doing wrong). Sadly, it comes at a huge cost in performance, though, making it unsuitable for production.
Not on, though. Xdebug is now available on all Grid environments, secure and without a performance loss.

Switching phubb’s HTTP client – Christian Weiske

phubb is a WebSub hub that notifies subscribers in realtime when your website is updated.

Up to this year, phubb sent HTTP requests (GET + POST) with file_get_contents() and a HTTP stream context – see my previous example.

But then I needed a 100% correct way of detecting a page’s Hub URL, and copied the code from phinde, my blog search engine. With that I introduced a dependency to PEAR’s good old HTTP_Request2 library and I decided to use that library for all requests.

Unfortunately, now the problems began: During development I got an error in about one of 10-20 requests on my machine and could not find the cause:

PHP Fatal error: Uncaught HTTP_Request2_MessageException: Malformed response: in HTTP/Request2/Adapter/Socket.php on line 1019 #0 HTTP/Request2/Adapter/Socket.php(1019): HTTP_Request2_Response->__construct('', true, Object(Net_URL2))
#1 HTTP/Request2/Adapter/Socket.php(136): HTTP_Request2_Adapter_Socket->readResponse()
#2 HTTP/Request2.php(946): HTTP_Request2_Adapter_Socket->sendRequest(Object(phubb\HttpRequest))
#3 phubb/src/phubb/HttpRequest.php(22): HTTP_Request2->send()
#4 phubb/src/phubb/Task/Publish.php(283): phubb\HttpRequest->send()
#5 phubb/src/phubb/Task/Publish.php(248): phubb\Task_Publish->fetchTopic(Object(phubb\Model_Topic))
#6 phubb/src/phubb/Task/Publish.php(77): phubb\Task_Publish->checkTopicUpdate('http://push-tes...')
#7 in HTTP/Request2/Response.php on line 215

The socket adapter has this problem, and I did not want to try to debug that strange problem. (No idea if the cURL one has it; I do not want to rely on php-curl). Finding a new HTTP library was the only option.

New HTTP library

The PHP Framework Interop Group has several HTTP-related proposals; one of them PSR-18: HTTP Client. Now that we have a standardized way to send HTTP requests in 2020, I should use a library that implements it.

The psr-18 topic on Github listed some clients:

Symfony’s HTTP client was among them, and it provides a mock client for unit tests! Unfortunately, it also introduces a million dependencies.

There were two others that looked ok-ish on first sight (diciotto and http-client-curl) but both of them had no mock client, and the latter was even curl only. Again nothing for me.

Then I found PHP-HTTP that promises a standard interface for HTTP clients in PHP, and it supports PSR-18! It even has a socket client that has nearly no dependencies, and a mock client for unit tests. I’ll try that one for now. + Lando: local dev in perfect sync with the cloud – removes a major pain point for developers: having to invest time in managing servers, virtual machines, or containers. Instead, enables developers to focus 100% of their time on their code. Since the beginning, has provided instant cloning capability, so dev teams can work on perfect copies of their production sites in the cloud for every Git branch.
Now, in partnership with Lando, we’re extending that capability to the desktop.

Taking your application to SaaS: a business decision –

Why have some great apps not evolved to SaaS? With new technology they still can.
For digital agencies and established software vendors, this blog offers insight into how easy it is now to launch and manage a full cloud SaaS offering with a PaaS. In my last article, I shared the recent story of a white-label client who launched their software-as-a-Service cloud offer and grew in value from 2.5x to 12x revenue over two short years.