Remi ColletSmall history about QA (21.3.2019, 15:10 UTC)

Despite I'm mainly a developer, I now use most of my time on doing QA on PHP projects.

Here is, around release of versions7.2.17RC1 and 7.3.4RC1 a report which should help to understand this activity.


1. Presentation

Usually, tests are done by PHP developers, particularly thanks to travis and then by users who will install the RC version available 2 weeks before a GA version.

The PHP project follow a release process (cf README.RELEASE_PROCESS) which gives 2 days between the preparation of a version, the Tuesday on git, and the Thursday its announcement in the mailing lists. These 2 days are especially designed to allow the build of binary packages (mostly by Microsoft and often by me for my repository) and to allow a last QA check which mays allow to discover some late issue.

When the new versions were available (on Tuesday afternoon) I start building the packages for my repostiory, givinf more coverage than the current travis configuration:

  • Fedora 27 to 31
  • RHEL 6, 7 and 8-Beta
  • i386 and x86_64
  • NTS and ZTS
  • various compiler versions  (GCC 4 to 9) and system library versions

I also run the build of the 7.3.4RC1 package in Fedora rawhide to trigger the re-build of all the PHP stack in Koschei, one of the CI tools of the Fedora project.

Notice : time to build all the packages for all the targets is about 3h for each version !  (I really need a faster builder).


2. Discoverd issues

2.1. Failed tests with pcre2 version 10.33RC1

Already available in rawhide, this version introduce a change in some error message, making 2 tests to fail.

Minor issue, fixed in PHP 7.3+: commit c421d9a.

2.2. Failed tests on 32-bit

In fix of bug #76117 the output of var_export have changed, make 2 tests to fail on 32-bit.

After confirmation by the autor of the change, tests have been fixed in PHP 7.2+ : commits a467a89 and 5c8d69b.

2.3. Regression

Koschei allow to discover very quickly a important regression in the run of the "make test" command. After digging, this regression was introduced in the fix of bug #77609, read the comments on the commit 3ead672.

After discussion between the Release managers, it have been choosen to:

  • revert this change to get back to a sane situation
  • to re-run the release process (new tag onr git)

The version which wil be announced shortly will not be affected byt this regression.


3. Conclusion

To ensure of the quality of PHP, of no regression is a complex, long and serious work. Thanks to all the actors, developers, QA team and users, this works pretty well.

So, if you use PHP in a development environment, it is essential to install the RC versions to detect and report us quickly any problem, so we can react before the finale version.

For users of my repository, the RC versions of PHP and various extensions are nearly always available in the testing repositories.


Ken GuestUpgrading to PHP 7.1.27 – how to fix the GPG error: error. (21.3.2019, 09:22 UTC)

If, like me, you’re still using PHP7.1, then you should upgrade to the most current security release which is 7.1.27 and was released on the 7th of March. Prior to that we were on 7.1.24 and missed out on fixed for a number of CVEs that were addressed in 7.1.26  and 7.1.25 – and fixes for a segmentation fault or two as well.

This morning, doing this on Debian Jessie yielded the error:

W: An error occurred during the signature verification.
The repository is not updated and the previous index files will be used.
GPG error: jessie InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY B188E2B695BD4743

This is because Ondřej Surý – who maintains the packages there – had to change over to a new DPA signing key as it was present on a server which got compromised.

This means that to install packages from there since the new one was switched to, I needed to download the new key:

# wget -O /etc/apt/trusted.gpg.d/php.gpg href="

After doing that a quick apt-get update set things straight again and apt-get upgrade could then carry on and move things along to 7.1.27.

Realising then that we’d missed out on upgrading to 7.1.27 sooner, I’ve added an additional check to our own product’s status page to determine whether the version of PHP being used is the newest “on-branch” version. It looks something like:

* Get the current/latest version released on branch x for PHP_VERSION.
* @param string $version Branch/Version to check for. e.g. 7.1 or 7.1.23...
* @return string
function getLatestPHPReleaseOnBranch($version)
    $v = explode(".", $version);
    $branch = "{$v[0]}.{$v[1]}";
    $major = $v[0];
    if (extension_loaded('curl')) {
        $url = "";
        $curl = curl_init($url);

        // Use browser's user agent string.
        $agent = $_SERVER['HTTP_USER_AGENT'];

        curl_setopt($curl, CURLOPT_USERAGENT, $agent);
        curl_setopt($curl, CURLOPT_FAILONERROR, true);
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        $json = curl_exec($curl);
        $decoded = json_decode($json, true);
        $version = $decoded[$major][$branch]['version'];
        return $version;
    } else {
        return null;
$latestPHP = getLatestPHPReleaseOnBranch(PHP_VERSION);
if ($latestPHP !== null) {
    echo "Using most recent on-branch PHP release? ", version_compare($current, $latestPHP, "==") ? "Yes" : "No", " (Latest release is $latestPHP Currently on ", PHP_VERSION , ")";

Please use this, or something similar, to determine when and if you need to update your PHP install.

Derick RethansPHP Internals News: Episode 2: PHP Compiler and FFI (21.3.2019, 09:02 UTC)

PHP Internals News: Episode 2: PHP Compiler and FFI

In this second episode of "PHP Internals News" we talk to Anthony Ferrara (@ircmaxell) about his PHP Compiler project, and the new FFI functionality that has made it into PHP 7.4.

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


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

Become a Patron!
Evert Pot416 Range Not Satisfiable (19.3.2019, 15:00 UTC)

It’s possible for a client to request partial responses from a server. For example, a client might only want the first 5 minutes of a video, or the last 100 lines of a log file.

HTTP clients and servers can do this with range requests.

For example, this request asks for the first 100 bytes:

GET / HTTP/1.1
Range: bytes=1-100

If a server doesn’t support range requests, it will return 200 OK and returns the entire resource. If it did support range requests, it can use 206 Partial Content and return just what the client asked for.

However, if a client requested a range that didn’t make sense, it can use 416 Range Not Satisfiable to indicate this. For example, maybe a file was 1024 bytes, and the client asked for bytes 2000-3000.

HTTP/1.1 416 Range Not Satisfiable
Content-Range: bytes */1000


Voices of the ElePHPantInterview with Ian Littman (19.3.2019, 11:30 UTC)

Show Notes

  • Longhorn PHP
  • Use the discount code elephpant to save $50 off your Longhorn PHP ticket!

This episode is sponsored by

The post Interview with Ian Littman appeared first on Voices of the ElePHPant.

Matthias NobackStyle Guide for Object Design: Release of the PHP edition (19.3.2019, 10:30 UTC)

With a foreword by Ross Tuck

Today I've released the revised edition of my latest book "Style Guide for Object Design". Over the past few weeks I've fixed many issues, smaller and larger ones. Ross Tuck and Laura Cody have read the manuscript and provided me with excellent feedback, which has helped me a lot to get the book in a better shape. I added many sections, asides, and even an extra chapter, because some topics deserve more detail and background than just a few paragraphs. Oh, and Ross wrote the kindest of forewords to kick off the book. It's available in the free sample of the book.

The book will be available at the initial "preview release" price of 20 dollars (with a suggested price of 29 dollars) but only until April 15th. Use this link to apply the discount:

What happens on April 15th?

Over the past few weeks I've been talking with some fine people from Manning, publisher of tech books. This resulted in a contract with them. They will republish the "Style Guide for Object Design". There will be an e-book, but also a printed version, which is great.

The book currently has code samples in PHP and contains some PHP-specific suggestions, but the Manning edition will have Java code samples, and no programming language or ecosystem-specific advice, hopefully making the book useful and appealing to a larger group of object-oriented programmers. This is an exciting thing for me as a book author, because I may be able to reach more people in this way.

I know that some readers prefer to read the PHP version, so that's why the version as it is now will be available until April 15th. From that moment on, you won't be able to buy it anymore. However, if you've bought the e-book from Leanpub, you will be granted access to the Manning Early Access Program (MEAP) for the book, meaning that you will eventually be able to read the Manning/Java edition too. Once this is possible, I'll send out an email to existing readers, and update the Leanpub page with instructions for joining the program.


If you already read (part of) the book, here's a summary of the most important changes, so you can decide if it'll be useful to download and read the new version. The full change log is in the back of the book and it includes linkes to the chapters and sections that have been updated.

  • Foreword

    • Added the foreword by Ross Tuck.
  • The lifecycle of an object

    • Rewrote the explanation about the two types of objects. What really defines these types is how they are related to each other. The first type uses the second type (services versus materials).
  • Creating services

    • Added a subsection: "Keeping together configuration values that belong together", which introduces a way to keep together configuration values that belong together.
    • Added an aside: "What if I need the service and the service I retrieve from it?", which answers a common question that was asked by the technical reviewer.
  • Creating other objects

    • Added a new section: "Don't use custom exception classes for invalid argument exceptions", explaining why you don't usually need custom exception classes for invalid argument exceptions.
    • Added an aside: "Adding more object types also leads to more typing, is that really necessary?", explaining some of the benefits of using object types instead of primitive types, just in case people are wondering if all that extra typing is really necessary.
    • Added another example to the section "Don't inject dependencies, optionally pass them as method arguments", explaining how you could rewrite the currency conversion logic using a simple services. Added a comment about the design trade-offs you have to make in this type of situation.
    • Added an aside about PHP's class-based scoping, explaining how it's possible that a named constructor can manipulate private properties directly.
    • Added a subsection "Optionally use the private constructor to enforce constraints" with an example showing how you can use the private constructor when you have multiple named constructors.
    • Finish the chapter with a new section: "The exception to the rule: Data transfer objects" about Data transfer objects, a type of object with less strict rules, which was not yet discussed in detail.
  • Manipulating objects

    • Added a new introductio

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

Christian WeiskePlay videos from Firefox on your Dreambox (14.3.2019, 15:57 UTC)

Two years after its last release, I finally found the time - and a reason - to rewrite the playVideoOnDreambox browser extension, making it compatible with newer Firefox versions.

The extension adds a button to Firefox that sends the currently playing video to the Dreambox satellite receiver - useful for showing a Youtube video to the family on the large TV screen.


Dreambox' media player does not support playing websites, so the extension needs to extract the URL of the video embedded on the current page. I did not implement this myself, but rely on youtube-dl for this.

Mozilla dropped support for "classic" extensions in Firefox 57; you have to use the "web extension" format now that severely restricts the things you can do. The main problem for me is that extensions cannot execute other programs on the computer anymore (unless the are registered manually with the browser and speak a certain protocol). This broke the my old extension that called youtube-dl directly.

I could have written a youtube-dl proxy script that users would need to register in their browser and that speaks said protocol. But instead I made the Firefox extension rely on the playVideoOnDreambox proxy application, just as the Android app does.

So when your browser shows some video and you click "Play on Dreambox", the extension sends the page URL to the proxy server web app running on some machine in your network. This proxy calls youtube-dl to find the video URL, and then instructs the Dreambox to play the video.


You can download the playVideoOnDreambox firefox extension version 0.6.0 from its homepage or the Mozilla Add-Ons page.

You migh be interested in the playVideoOnDreambox Android app that lets you "share" the video with your satellite receiver.

Evert PotAn OAuth2 middleware for fetch() (14.3.2019, 15:37 UTC)

I was a bit frustrated with the existing offerings for OAuth2 clients in Javascript. I heavily use the Fetch API directly, but Web API’s haven’t really caught up to have deep integration with OAuth2.

We were using client-oauth2, but the minified size of this library was close to 40kb which ended up being a majority of the size of our total Javascript code.

I realized what I really wanted was an OAuth2 client that acts as a middleware-style layer for Fetch, making OAuth2 refreshes transparent, and is a lot lighter in weight.

It only took 2 days to write a replacement that is good enough for my use-case, and I made it open source. It’s currently 3692 bytes minified, is written for typescript and has 0 dependencies.

Find it on Github. The library handles the ‘token’ part of OAuth2 flow, including:

  • authorization_code, password and client_credentials grant types.
  • It keeps an eye on access token expiry, and will automatically call refresh_token if they expired.
  • It exposes a simple hook that gets called when tokens get updated, allowing you to store the new tokens somewhere else (like LocalStorage).

It doesn’t however handle the ‘authorization’ part of OAuth2. Which means that if you use the implicit or authorization_code flow, you are responsible for redirecting the user, and when the user returns setting up the OAuth2 with the right code or accessToken value.


If you’re using the password grant type:

const OAuth2 = require('fetch-mw-oauth2');

const oauth2 = new OAuth2({
  grantType: 'password',
  clientId: '...',
  clientSecret: '...',
  userName: '...',
  password: '...',
  tokenEndPoint: '',

After this setup is complete, and now you can use the fetch functon on the oauth2 object, instead of the global one. It takes exactly the same parameters, as it just forwards the function with the correct Authorization header:

const result = await oauth2.fetch('', {
   method: 'POST',
   body: '...',

I hope this is useful to anyone else. Take a look at the project for more info!

Stefan KoopmanschapTake care of non-technical skills (14.3.2019, 11:15 UTC)

Full disclosure: I am one of the founders and current organizers of WeCamp, an event that has a focus on not just technical skills but also personal skills.

In my 20+ years of professional experience in the PHP/software development world, I've worked at many companies and been into many companies as a consultant or freelance developer. Many of the companies I've come in touch with had programs set up for training of their developers. Most of those programs focused on improving technical skills. This makes a lot of sense, because in the current tech world, things change so fast that you need continuous learning to improve. And there is nothing wrong with that.

In recent years, I've seen the focus of training shift a bit from mostly PHP-related subjects to the whole ecosphere of software and tooling around PHP. This is a great shift, because PHP developers don't just write PHP. They use tools like ElasticSearch and memcache, Git and continuous integration, AWS and Azure, and numerous other products that you don't instantly know how to use. Performance, security, quality, it's topics that get more and more attention and rightfully so.

With a few exceptions, however, I've found that many companies still seem to ignore another important part: personal development. I'm talking about things like communication skills, planning skills, a focus on personal happiness. About knowing where you want to go in your life and what to focus on. The human side of the developer. Because, despite what many recruiters would like you to think, a developer is more than just a resource. Developers are just like humans.

I've heard managers complain about developers not having good communication skills, but I've hardly ever seen those same managers look for ways to improve those skills for their developers. I've heard managers complain about the lack of planning skills, or the fact that their developers have a hard time structuring their work day, but I've often seen those same managers only consider technical training for those same developers. And yet, the first non-sponsored link when I search the web for planning skills training is an effective planning skills training. Same for searching for communication skills training. The first result is a learning tree training. And that's just the first results. Go down the results and you'll find a lot more.

WeCamp, a 5-day event focussing on improving both technical and non-technical skills that are essential to software development. We've received a lot of positive feedback on the key take-aways of the event being more than just technical skills. I am very proud of that. When we get feedback such as:

To developers, I'd say that the experience is unrivalled by anything in the market today. The coach's focus on your personal development is guaranteed to push you on exactly the points that need improving.

this means we've done our job. We push people to reflect their current position and where they're heading. We push them to evaluate if their current heading is what they really want. But we also help them set goals and achieve those goals. Whether this is about new tech they want to learn or non-tech skills they want to improve. Actually, when we asked what was the best thing about WeCamp 2017 in the evaluation questionnaire, one of the attendees responded with:

The blend of technical and personal development.

In that same questionnaire, when asked about why people would recommend WeCamp, we got things like:

Great learning and life experience and pushes you to get out of your comfort zone in a positive way.

I know I am biased because I'm very much involved in this event, but I really believe that by creating the safe space that we create for people to reflect on their life and career and by getting developers our of their comfort zone, we add a value that not many other events could.


If you or your developers are interested in WeCamp, please check out our website. If you have any questions, please do feel free to contact me.

Evert Pot415 Unsupported Media Type (12.3.2019, 15:00 UTC)

When a server receives a request with a body it doesn’t understand, it should return 415 Unsupported Media Type. Most commonly this is a good response for for example a POST or PUT request with an unknown Content-Type header.

The specification says that aside from inspecting the Content-Type header, the server may also return this after inspecting the body.

What this means is that if the client sent a request with a supported Content-Type, it may still return 415 if the contents of the request body were not supported by the server.

For example, a server might support specific JSON bodies, but the contents of the JSON payload didn’t validate, perhaps because it was missing a required property.

However, for the latter case it might be better to use 422 Unprocessable Entity. The description in the standards for 422 is slightly contradicting with the one for 415, but 422 seems to be more specifically for cases where the Content-Type was correct, the request was parsable, but semantically incorrect.

I would suggest the following approach to deciding the right status code:

  • If the Content-Type was not supported, use 415.
  • Else: If the request was not parsable (broken JSON, XML), use 400 Bad Request.
  • Else: If the request was parsable but the specific contents of the payload were wrong (due to validation or otherwise), use 422


POST /new-article HTTP/1.1
Content-Type: text/html

<h1>Another day, another blog post</h1>

HTTP/1.1 415 Unsupported Media Type
Content-Type: application/json

{"error": "This endpoint only supports text/markdown for new articles"}


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