planet PHP

Subscribe to planet PHP のフィード
People blogging about PHP
更新: 3時間 18分 前

Small history about QA

2019-03-22(金) 00:10:00

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.


カテゴリー: php

Upgrading to PHP 7.1.27 – how to fix the GPG error: error.

2019-03-21(木) 18:22:00

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.

カテゴリー: php

416 Range Not Satisfiable

2019-03-20(水) 00:00:00

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 References
カテゴリー: php

Interview with Ian Littman

2019-03-19(火) 20:30:00

@iansltx 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.

カテゴリー: php

Style Guide for Object Design: Release of the PHP edition

2019-03-19(火) 19:30:00
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)

カテゴリー: php

Play videos from Firefox on your Dreambox

2019-03-15(金) 00:57:00

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.

カテゴリー: php

An OAuth2 middleware for fetch()

2019-03-15(金) 00:37:00

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!

カテゴリー: php

Take care of non-technical skills

2019-03-14(木) 20:15:00

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.

One way to focus on more than just technology

As mentioned in my full disclosure at the start, I am one of the founders and current organizers of 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.

カテゴリー: php

415 Unsupported Media Type

2019-03-13(水) 00:00:00

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
Example 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"} References
カテゴリー: php

Interview with Keith “Danger” Casey

2019-03-12(火) 20:30:00

@caseysofyware Show Notes


This episode is sponsored by

The post Interview with Keith “Danger” Casey appeared first on Voices of the ElePHPant.

カテゴリー: php

WordPress and HTTPS-terminating proxies

2019-03-09(土) 20:15:00

A blog I am writing for was looking for a new place to host their website. Since we have a nice cluster with Rancher up and running, I offered to host the site. It's WordPress, so PHP, so how hard could it be, right?

I spent quite a few hours migrating everything. The initial migration to Docker was not that hard. There is a great official WordPress image for Docker, which makes it extremely easy to set up a new WordPress site in Docker.

The next thing is handling file uploads. Using the do-spaces-sync plugin this was easily set up to use DigitalOcean Spaces. It took a while to upload all images from the old wp-content/uploads to Spaces, but once that was done, I had it working immediately after setting it up. So far, this whole migration was a breeze.

Until I flipped the switch on the DNS and pointed it to our new hosting. I immediately got caught in an infinite redirect loop, and I had no idea why. I've spent hours turning off plugins, turning them on again. Debugging everything, watching logs. I could not figure it out. In the headers I did find a header saying that the redirect came from WordPress:

X-Redirect-By: WordPress

Eventually, I tried explaining the problem in the #wordpress channel in the PHPNL slack and as I'm typing my explanation something dawns on me...

Our Rancher setup has a load balancer that terminates the HTTPS then forwards an internal request to the container using http. But in WordPress, I have configured the siteurl to be https://. So WordPress gets a request using http, figures out it should be using https, and redirects. This causes the infinite redirect loop!

Of course, I wasn't the first to encounter this problem. Once I know what the problem was, searching the Internet quickly gave me the solution. In Wordpress Codex of course. The only thing I needed to do was add a single line to my .htaccess file:

SetEnvIf X-Forwarded-Proto https HTTPS

Once I did that, rebuilt my containers and deployed them to Rancher, the problem was solved. All of a sudden, everything worked.

カテゴリー: php

New domain

2019-03-07(木) 23:10:00

I've had the domain for ages. It's been with me since 2004. However, since I recently got a brand new .dev domain, I decided it was time for a change. Since I can't even remember how I came up with the old name, it's time for a change. A new name that is easy to recognize, easy to remember and easy to link to me.

The new domain name for this blog is:

It only makes sense to switch to this domain. Skoop has been my nickname for as long as I have access to the Internet. And since my main occupation is still development, this switch makes sense.

Now, to find interesting topics to blog about again...

カテゴリー: php

PHP 7.2.16 Released

2019-03-07(木) 09:00:00
The PHP development team announces the immediate availability of PHP 7.2.16. This is a security release which also contains several minor bug fixes.All PHP 7.2 users are encouraged to upgrade to this version.For source downloads of PHP 7.2.16 please visit our downloads page, Windows source and binaries can be found on The list of changes is recorded in the ChangeLog.
カテゴリー: php

PHP 7.1.27 Released

2019-03-07(木) 09:00:00
The PHP development team announces the immediate availability of PHP 7.1.27. This is a security release which also contains several bug fixes.All PHP 7.1 users are encouraged to upgrade to this version.For source downloads of PHP 7.1.27 please visit our downloads page, Windows source and binaries can be found on The list of changes is recorded in the ChangeLog.
カテゴリー: php

PHP 7.3.3 Released

2019-03-07(木) 09:00:00
The PHP development team announces the immediate availability of PHP 7.3.3. This is a security release which also contains several bug fixes.All PHP 7.3 users are encouraged to upgrade to this version.For source downloads of PHP 7.3.3 please visit our downloads page, Windows source and binaries can be found on The list of changes is recorded in the ChangeLog.
カテゴリー: php

Interview with Jeremy Lindblom

2019-03-06(水) 21:00:00

@jeremeamia Show Notes


This episode is sponsored by

The post Interview with Jeremy Lindblom appeared first on Voices of the ElePHPant.

カテゴリー: php

414 URI Too Long

2019-03-06(水) 00:00:00

The URI or path of a HTTP request doesn’t have any hard limits in terms of how long it’s allowed to be.

However, Browsers and search engines have limits, and on the server side it’s a good idea to limit the length of the URI to combat certain denial-of-service attacks or bugs.

Based on limits of browsers, it’s a good idea to try and not exceed 2000 bytes for the uri.

When a client does exceed it, the appropriate status code to return is 414 URI Too Long.

Example HTTP/1.1 414 URI Too Long Content-Type: text/html <p>Insufficient level of conciseness in request</p> References
カテゴリー: php