Evert PotThe end of the HTTP series (18.9.2019, 15:00 UTC)

Last year I quit my job at Yelp, and wanted to be a more active blogger again. I thought it would be a neat idea to write 1 post per week, one for each HTTP status.

This was quite an undertaking, and I ended up having to write 67 blog posts, one each week.

Some stats:

  • 67 HTTP statuses.
  • 70 blog posts written.
  • 18091 words written.
  • Articles written in 9 cities, 5 countries.
  • 53,511 page views.

Was it worth it? I don’t really know. I had higher hopes in terms of popularity. Most of the traffic comes from search results and hotlinks, but I don’t think I achieved what I had really hoped: build a bit more of a consistent audience.

I think part of the problem with building audiences is that people don’t really subsribe to RSS feeds anymore. I offered a twitter feed and a mailing list as well, but who wants to receive more emails? It seems that most people consume their technical content from aggregrators like Hackenernews and silos like Medium.

It feels like a big loss that RSS feeds have gone out of fashion, not just for me but also the industry. I still miss the blogging revolution of the mid-2000’s. Or maybe HTTP statuses are just wayy too boring, and I mistook my own interest with everyone else’s.

Still, I’m glad that I saw it all the way through, and it’s nice to see that people seem to find these pages on google, or use them as a reference. There’s definitely a few in there that have some nuance, so I hope I positively contributed to the API ecosystem.

For the few that followed this series, thank you!

Voices of the ElePHPantInterview with Katie McLaughlin (14.9.2019, 21:31 UTC)
Voices of the ElePHPantInterview with Junade Ali (14.9.2019, 15:05 UTC)
Derick RethansPHP Internals News: Episode 27: Argument Information (12.9.2019, 08:27 UTC)

PHP Internals News: Episode 27: Argument Information

In this episode of "PHP Internals News" I chat with Nikita Popov (Twitter, GitHub) about adding information about arguments and return types to PHP's reflection mechanism.

The RSS feed for this podcast is https://derickrethans.nl/feed-phpinternalsnews.xml, you can download this episode's MP3 file, and it's available on Spotify and iTunes. There is a dedicated website: https://phpinternals.news

Show Notes


Music: Chipper Doodle v2 — Kevin MacLeod (incompetech.com) — Creative Commons: By Attribution 3.0

Become a Patron!
Rob AllenSlim4-empty: minimal Slim 4 starting point (11.9.2019, 10:00 UTC)

To simplify creating a new Slim 4 project, I've created slim4-empty which does this for me.

To use it:

$ composer create-project akrabat/slim4-empty my-new-project

and you're done!

The my-new-project directory is created and contains Slim 4 along with a minimally viable public/index.php to get you going. You can then run it with the PHP built-in server:

php -S -t public/

And navigate to https://localhost:8888 to view "Hello World" in your browser.

What does it contain?

Slim4-empty provides no structure to your project and adds no extraneous components at all. You do the rest. It simply contains the following:

Slim & Slim-Psr7

The composer create-project command will create a new directory (my-new_project) and then within it will install Slim and Slim-Psr7. Of course with Slim 4, you are free to use any PSR-7 component, but I happen to like our one :)


Within the public directory, slim4-empty provides a minimal index.php:



use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Slim\Factory\AppFactory;

require __DIR__ . '/../vendor/autoload.php';

// Create app
$app = AppFactory::create();

// Register middleware
$app->addErrorMiddleware(true, true, true);

// Register routes
$app->get('/[{name}]', function (
    ServerRequestInterface $request,
    ResponseInterface $response,
    array $args
): ResponseInterface {
    $name = $args['name'] ?? 'world';
    $response->getBody()->write("hello $name");
    return $response;

// Run app

As you can see from the comments, it does the following:

  • Create the App instance – The AppFactory does all the hard work here for us by finding the PSR-7 component and registering it.
  • Register a minimal set of middleware – Slim's default error handling is flexible and you should use it. The body parsing middleware is mostly useful for APIs, but doesn't impact performance for standard websites. The routing middleware is required to route from a URL to a handler. If it's missing, it'll be added by slim, but this is a case where I prefer to be explicit.
  • Add a route for / – Nothing works without a route! This is a minimal one that you can change to suite your needs.
  • Run the application – This will run the middleware stack and then run the route handler and send the response back to the client (web browser).

Who can remember all that? I have to go and copy/paste it, which is why I wrote slim4-empty!

That's it

Maybe it's useful to someone else other than me; I'm certainly finding it helpful!

Voices of the ElePHPantInterview with Katie McLaughlin (10.9.2019, 23:03 UTC)
Evert Pot511 Network Authentication Required (10.9.2019, 15:00 UTC)

511 Network Authentication Required is a status that can be used by for example captive portals to signal to computers that they need to go through some kind of sign-in after connecting to a WiFi network.

You might see these kind of sign-in screens when for example connecting to the WiFi at a coffee shop.

Most operating systems and browsers detect this log in screen by making a HTTP request to a standard url. These are some real examples:

  • http://www.msftconnecttest.com/connecttest.txt
  • http://connectivitycheck.gstatic.com/generate_204
  • http://captive.apple.com/hotspot-detect.html
  • http://detectportal.firefox.com/success.txt

Browsers and operating systems will do an HTTP request to one of those urls, and expect a string like success to appear. If it doesn’t appear, it means a router might be blocking it and a pop-up will appear to log into the network.

One of the issues with this approach is that it might not be possible to for a client to distingish a ‘correct’ response, vs. a HTTP response that was intercepted by the network and a captive portal being served instead.

It is a type of man-in-the-middle attack, so returning a captive portal interface instead of the real response might cause systems to malfunction and caches to be primed with bad data.

The 511 Network Authentication Required status code was invented as a default status code for captive portals to return when intercepting a HTTP request. This status signals that it was returned by an intermediate.

The full HTTP response should contain a link to where the user may log in.

The example given from the RFC is as follows:

HTTP/1.1 511 Network Authentication Required
Content-Type: text/html

     <title>Network Authentication Required</title>
     <meta http-equiv="refresh"
           content="0; url=https://login.example.net/">
     <p>You need to <a href="https://login.example.net/">
     authenticate with the local network</a> in order to gain


Voices of the ElePHPantInterview with David Bisset (10.9.2019, 11:30 UTC) Link
Derick RethansXdebug Update: August 2019 (10.9.2019, 08:25 UTC)

Xdebug Update: August 2019

This is another of the monthly update reports in which 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 August, I worked on the following things:

2.8.0beta2 Release

This second beta release addresses a lot of issues that were still outstanding for the 2.8 release. This included simple issues like Wrong name displayed for Recoverable fatal errors and Code Coverage misses fluent interface function call. The trickiest bug was related to the DBGp debugging protocol.

I test Xdebug's implementation of the DBGp protocol by having a file with the PHP script to debug and then a phpt test that has a set of commands to run against that file. As an example, for one of the fixed bugs, the script looks like:

<?php function breakpoint1()
        echo base64_encode("testing"), "\n";


And the phpt test looks like:

<?php require 'dbgp/dbgpclient.php';
$filename = realpath( dirname(__FILE__) . '/bug01388-01.inc' );

$commands = array(
        'feature_get -n resolved_breakpoints',
        "breakpoint_set -t line -f file://{$filename} -n 4",
        'feature_set -n resolved_breakpoints -v 1',
        'feature_get -n resolved_breakpoints',
        "breakpoint_set -t line -f file://{$filename} -n 4",

dbgpRunFile( $filename, $commands );

The third command sets a breakpoint on line 4 (the echo statement) and then does various things related to breakpoint resolving. The "remote log" that is generated by the test is then compared (after some regexp replacements) with the expected output.

Because I run the script in a new process, I have some methods in place to also collect the output of the script (both stdout and stderr). I don't usually have stderr on, as there are a few false positives, but when I tested with this in the past, I noticed that one test caused a segmentation fault.

After a few hours of trying to find out the problem, I noticed that this would only happen in the init state (when the debugger first connects to the IDE, and when the IDE can enable features and send breakpoints). If in this init state the IDE would send the detach command, Xdebug would crash. This detach command can be used by an IDE to disengage the debugger, with the script continuing to run afterwards.

Due to an implementation bug related to whether the debugger connection was active or not, a detach in the init state would mark the connection active, while the connection was already cleaned up before hand. This caused Xdebug to access memory, that was already freed (which is a bad thing to do). The fix was luckily quite simple.

IANA Port Assignment

As a result of a twitter conversation that I had, I tried applying for an "assigned port" for the DBGp protocol. As some of you might be aware, Xdebug shares the same default port (9000) as PHP-FPM. This has caused confusion in the past, so I was hoping to avoid future problems with Xdebug 3 by asking IANA to assign me one. However, IANA declined by application by somewhat vague comments about "security" and not needing one because DBGp runs on a LAN.

As to the security aspect, they require authentication and encryption for new protocols, and of course DBGp isn't new. I would like to add an encryption layer to DBGp, but I can't require this right away, as that would mean no IDE can talk DBGp any more. Requiring authentication (i.

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

Chris ShiflettLeaders Wanted (6.9.2019, 17:55 UTC)

In the best companies, everyone is a leader. Decisions are made by those best suited to make them, everyone feels trusted and respected, and a shared purpose provides unity and motivation.

I’ve been trying to be a better leader my entire career, and I still have much to learn. Nevertheless, some lessons I’ve learned along the way have stood the test of time, and I’d like to share them with you.

Mind your morale

Morale is a currency; spend it wisely.

One of the most important responsibilities of any leader is to manage the morale and energy of the team. If you’re a freelancer, self-awareness is key, because you must manage yourself, and tending to your own morale is critical to your success.

Managing morale doesn’t mean avoiding hard work. In my experience, providing an environment that lets people do their best work is what keeps morale high.

Decide who decides

Clearly defined roles and responsibilities help everyone. A leader’s job is to trust the right people to make the right decisions, and to provide the necessary context to do so.

When someone is a designated decision-maker, they are more likely to listen carefully to other views, because they don’t have to spend energy presenting or defending their own. Others will feel heard, because the decision-maker is actually listening. Everyone wins.

Choose words carefully

Language is important. The words we use shape our perspective and the perspectives of everyone we work with.

Make we a habit. They didn’t make a mistake; we made a mistake. The client doesn’t have a big opportunity; we have a big opportunity.

When you’re certain about something, say so, but also make it clear when you’re not. Expressing uncertainty doesn’t erode trust, but expressing certainty and being wrong does.

Set healthy boundaries

Communication is good, but be deliberate about it. The cost of real-time, always-on communication tools shouldn’t be overlooked, especially when used with clients. When possible, stick to email and scheduled meetings.

Avoid working outside of normal working hours, too. It’s more sustainable, and often more productive, to use a strict work schedule to help you and your team stay focused and driven. Don’t let the possibility of after-hours work excuse lacklustre performance during the day.

Make meetings count

Meetings are often unfairly maligned. It’s true that a poorly-organized meeting can be disruptive and wasteful, but a good meeting can be invaluable.

Every meeting needs a goal. Agendas are good, but goals are better. With a clear goal, it’s easy to intuit when the meeting is the least bit off-track, so you can correct course as you go. It’s also worth making clear if a meeting is meant to be divergent (new ideas welcome) or convergent (time to reach a consensus).

Make a habit of designating someone to take notes, and email the notes to everyone after the meeting. This will help you move more quickly, because no one will be worried about missing something. It also gives you a good excuse to exclude optional attendees; they can just read the notes. Small meetings without bystanders are more efficient.

Create your own rules

Some of the best lessons will come from your own experience.

A rule we adhere to on my team, for example, is to never estimate someone else’s work. This gives each person a sense of responsibility to the schedule and helps prevent unreasonable expectations.

Try to avoid treating any rule as dogma, however. ‘It depends’ is the only rule that is always dependable, so be willing to make an exception for a really good reason.

Stay humble

Leadership is a skill that requires study and practice, just like any other, and learning from one another is a great way to continue to improve. As peers, we share common threads, so the lessons we learn do as well.

I’m convinced that the most meaningful work is teamwork. Let’s learn together and work together to deliver on the web’s promise. Leaders wanted.

The original version of this article was commissioned for New Adventures magazine, January 2019.

LinksRSS 0.92   RDF 1.
Atom Feed   100% Popoon
PHP5 powered   PEAR
ButtonsPlanet PHP   Planet PHP
Planet PHP