PHP Versions Stats - 2017.2 Edition

It's stats o'clock! See 2014, 2015, 2016.1, 2016.2 and 2017.1 for previous similar posts.

A quick note on methodology, because all these stats are imperfect as they just sample some subset of the PHP user base. I look in the packagist.org logs of the last month for Composer installs done by someone. Composer sends the PHP version it is running with in its User-Agent header, so I can use that to see which PHP versions people are using Composer with.

PHP usage statistics

November 2017 (+/- diff from May 2017)

All versions Grouped
PHP 7.1.10 11.63% PHP 7.1 36.63% (+18.99)
PHP 7.0.22 7.95% PHP 7.0 30.76% (-5.36)
PHP 5.6.31 7.38% PHP 5.6 23.28% (-8.16)
PHP 5.6.30 7.23% PHP 5.5 6.11% (-4.5)
PHP 7.0.24 5.45% PHP 5.4 1.51% (-1.6)
PHP 7.1.11 4.55% PHP 5.3 0.76% (-0.22)

A few observations: I find it quite incredible that PHP 7.1 is now the most used version, even though Ubuntu LTS does not yet ship with it. I don't know if it means people use Docker or alternative PPAs but regardless it is good news! For the first time since I started these blog posts, the version usage actually matches the order in which they were released, with the older ones having less and less usage. That's also great news. We have a total of 90% of installs done on PHP versions that are still maintained, which is awesome. If you are still on 5.6 or 7.0 though you only have one year of security fixes left so consider upgrading to 7.2 which should come out in the next week or two.

Here is the aggregate chart covering all my blog posts and the last four years.

PHP requirements in Packages

The second dataset is which versions are required by the PHP packages present on packagist. I only check the require statement in their current master version to see what the latest requirement is, and the dataset only includes packages that had commits in the last year to exclude all EOL'd projects as they don't update their requirements.

PHP Requirements - Recent Master - November 2017 (+/- diff from Recent Master May 2017)

5.2 1.28% (-0.24)
5.3 18.75% (-4.4)
5.4 20.29% (-4.12)
5.5 19.07% (-4.63)
5.6 20.4% (3.59)
7.0 14.85% (6.12)
7.1 5.32% (3.65)
7.2 0.03% (0.03)

This moves at a decent pace with EOL'd versions slowly being abandoned. I still think it could go faster though ;) Please consider bumping to PHP 7.0 at the very least when you update your libraries.

November 13, 2017 // News, PHP // Post a comment

PHP Versions Stats - 2017.1 Edition

It's stats o'clock! See 2014, 2015, 2016.1 and 2016.2 for previous similar posts.

A quick note on methodology, because all these stats are imperfect as they just sample some subset of the PHP user base. I look in the packagist.org logs of the last month for Composer installs done by someone. Composer sends the PHP version it is running with in its User-Agent header, so I can use that to see which PHP versions people are using Composer with.

PHP usage statistics

May 2017 (+/- diff from November 2016)

All versions Grouped
PHP 5.6.30 14.73% PHP 7.0 36.12% (+1.11)
PHP 7.0.15 9.53% PHP 5.6 31.44% (-6.02)
PHP 5.5.9 6.12% PHP 7.1 17.64% (+16.28)
PHP 7.0.17 6.00% PHP 5.5 10.61% (-8.32)
PHP 7.1.3 5.88% PHP 5.4 3.11% (-2.29)
PHP 7.1.4 3.65% PHP 5.3 0.98% (-0.62)

A few observations: With a big boost of PHP 7.1 installs, PHP 7 overall now represents over 50%. 5.3/5.4 are really tiny and even 5.5 is dropping significantly which is good as it is not maintained anymore since last summer. That's a total of 85% of installs done on supported versions, which is pretty good.

And because a few people have asked me this recently, while HHVM usage is not included above in the graph it is at 0.36% which is a third of PHP 5.3 usage and really hardly significant. I personally think it's fine to support it still in libraries if it just works, or if the fixes involved are minor. If not then it's probably not worth the time investment.

Also.. since I now have quite a bit of data accumulated and the pie chart format is kind of crappy to see the evolution, here is a new chart which shows the full historical dataset!

It is pretty interesting I think as it shows that 5.3/5.4/5.5 had people slowly migrating in bunches and the versions peaked at ~50% of the user base. On the other hand 5.6/7.0/7.1 peak around 35% which seems to indicate people are moving on faster to new versions. This is quite encouraging!

PHP requirements in Packages

The second dataset is which versions are required by all the PHP packages present on packagist. I only check the require statement in their current master version to see what the latest is.

PHP Requirements - Current Master - May 2017 (+/- diff from November 2016)

5.2 2.13% (-0.22)
5.3 37.6% (-3.65)
5.4 28.38% (-1.74)
5.5 17.11% (+0.13)
5.6 9.37% (+3.15)
7.0 4.61% (+1.53)
7.1 0.81% (+0.81)

A few observations: This is as usual moving pretty slowly. I think I can give up trying to advise for change, it doesn't seem to be working.. On the other hand it looks like Symfony is going to use 7.0 or 7.1 for it's v4 to come out later this year, so hopefully that will shake things up a bit and make more libraries also realize they can bump to PHP 7.

PHP Requirements - Recent Master - May 2017 (+/- diff from Current Master November 2016)

In response to Nikita's comment below I ran the requirements numbers for packages that had some sort of commit activity over the last year. This excludes all stale/done packages and looks much more encouraging, but the difference points are probably overly large because they compare to the old numbers which included everything, therefore take those with a pinch of salt, and in the next six months update I'll have more trusty numbers.

5.2 1.52% (-0.83)
5.3 23.15% (-18.1)
5.4 24.41% (-5.71)
5.5 23.7% (+6.72)
5.6 16.81% (+10.59)
7.0 8.73% (+5.65)
7.1 1.67% (+1.67)

May 06, 2017 // News, PHP // Post a comment

Goddamn it.

It's not often that one messes up really bad. But today is my day apparently.

TL;DR: I accidentally wiped a github organization that had a few popular repos on it. But it's all fixed now.

How the heck did this happen?

I was trying to remove a private repository, called nelmio, which incidentally has the same name as the organization it was in, so nelmio/nelmio. Then this happened:

  • I wanted to check repo permissions so I went to https://github.com/nelmio/nelmio/settings/collaboration then followed a team link which led to https://github.com/orgs/nelmio/teams/foo
  • Then I was like OK let's go back in the settings tab to delete this repo, except at this point the settings tab points to https://github.com/organizations/nelmio/settings/profile (i.e. the org settings not the repo)
  • So at the end of the settings tab I see the familiar red delete button, hit it, it tells me to type the repo name (nelmio) as usual, but obviously I've done this many times so I don't read the fine print. It turns out in this case it wanted me to confirm the org name and not repo name.
  • As I click "Confirm Delete" I saw that something in the message wasn't quite familiar, but then it reloaded the page and I find myself on the github home. I'm like "That's odd!", then more or less 2 seconds later this horrible feeling in my guts is confirmed, the entire org was wiped.

Mitigation

I immediately emailed GitHub support, and am still waiting for an answer. I kinda wish there was a hotline for such cases, even if it was billed 10 bucks a minute :)

After doing so, I started re-pushing repos into a new organization (nelmiobackup). I then changed the packagist.org package URLs to point to this new org, so that at least package installs should continue working relatively normally for the time being.

I did not want to re-create a nelmio org as I thought this might hamper any recovery effort by the github support folks, but someone had the great idea to do that for me, so now that the potential damage is done and they added me as owner, I forked everything from nelmiobackup to nelmio so that it's present at the old URL for people doing installs using composer.lock files that point to the old URL.

I hope GitHub will be able to fix this, but if not apparently http://ghtorrent.org/ has a ton of github data. We'll see what can be done.

Updates

Update1: GH support answered, it seems they can restore. I had to rename nelmio to nelmio-old for now to make room for the restore, so clones with old URLs will temporarily fail again.

Update2: All restored, I only have to re-create teams within the org, no biggie :) Total time was a bit over 1h from deletion, which isn't too bad in the grand scale of things.

P.S: If you feel like comparing this to the left-pad incident, this is quite different because I fucked up accidentally while the guy in question did it intentionally. I guess I can't stop you though.

P.P.S: If you want to laugh or say anything mean, please go away. I don't want to hear it right now. It is stressful enough as it is, and I am doing what I can.

May 31, 2016 // News // Post a comment

Composer goes Gold

Five years ago today, Composer was born. In some ways it feels like yesterday, at least it doesn't feel like five years went by. In other ways it seems like a lifetime ago, and I can barely remember what it was like to write PHP code without having a whole ecosystem at my fingertips.

Composer 1.0.0

Today I have the pleasure of announcing that the first 1.0.0 stable release is out and available for immediate download!

It has been a long time coming, but we fixed a few last critical issues in the last few months that finally allow me to take this step. Going forward I plan on releasing more frequently as well ;)

Update channels

One big change that happened recently is that by default the Composer installer and composer self-update both install stable releases by default. This is great to avoid bad surprises if you run self-update as part of your deployment, but it also means that the feedback loop gets longer for us when we do changes. Therefore I really hope that we can get enough people running frequent self-updates using the preview (alpha/beta/..) and especially snapshot (dev builds) channels.

My recommendation would be to run regular updates for deployment/builds to have stability, run self-update --preview in CI if you can to make sure you test at least pre-release versions. And on dev environments composer self-update --snapshot would give you the latest and shiniest Composer has to offer. This will ensure we spot regressions or mistakes as early as possible, and thus avoid breaking things in stable releases.

Composer Gold Edition

Finally, in an attempt to mark the fact that Composer has finally gone gold, I wanted to do something special.

My girlfriend had a brilliant idea, and a few days and a couple express deliveries later here we are. We made an actual Composer gold master copy of the 1.0 release, on a floppy!

Collector items are no fun if you can't collect them though, so you can head to eBay now to bid on it if you'd like to own it!

Here's to the next five years (for the 2.0, hah.)!

April 04, 2016 // News, PHP // Post a comment

Toran Proxy Updates

Over the last month I spent quite some time bringing Toran Proxy up to speed with the times, and added a few features along the way. I haven't blogged about it in a while so I thought an update was overdue.

Toran what?

First of a all a quick note about Toran Proxy, in case you don't know about it. You can check the website for details but in two words it is a way to host private packages, as well as to mirror github, packagist and others so that if they break down you can still run composer installs from your Toran setup. It is a paid product but money goes to fund Composer development and Packagist hosting as well so you will hopefully agree it is for a good cause ;)

Drupal, Magento and WordPress support

v1.3 added the capability to mirror other public repositories, like the WPackagist one for WordPress, the Firegento repo for Magento or Drupal's Packagist setup. These projects have large plugin ecosystems and they have chosen to publish them on their own repositories instead of using Packagist. Toran now lets you add these in the settings so that you can mirror public packages transparently no matter if they come from Packagist or another public repo.

Performance and UI improvements

It used to be a bit slow to run updates with many packages, as it was hitting the PHP application for every package. This has been fixed and updates should now run a lot faster.

As for UI, the new release brings an actual package detail page for your private packages so you can see which versions are available and what they require, as well as trigger instant updates from the UI.


If you haven't yet, go try it out with the personal edition and I hope you will then consider getting a license to use it in your company!

April 04, 2016 // News, PHP // Post a comment

The Road to Monolog 2.0

Monolog's first commit was on February 17th, 2011. That is almost 5 years ago! I have now been thinking for quite a while that it would be nice to start on a v2, and being able to drop some baggage.

One of the main questions when doing a major release is which minimum PHP version to support going forward. Last summer I decided I wanted to do a big jump from 5.3 and directly target PHP 7. It provides a lot of nice features as well as performance improvements, and as Monolog is one of the most installed packages on Packagist I wanted to help nudge everyone towards PHP 7.

Back then 7.0 was not out though, so I played around a bit but I did not do much progress. Another point that was limiting me was that I did not want to bother people adding Monolog to their project via composer require monolog/monolog as that used to just take the last release available.

However PHP 7.0 is now out, and as you may have seen in my previous post I have fixed the issue in composer require. I also emailed several projects that had dangerous requirements on Monolog a few months ago to ensure they would not upgrade to the 2.0 version accidentally.

The road forward

Monolog's master branch now targets PHP 7, and the branch-alias has been updated to 2.0 so work can now fully begin on the upcoming version. There is an old issue with a list of ideas and tasks for 2.0, but I am open to more ideas. There is also a 2.0 milestone with some more issues and PRs that have to be considered for inclusion.

If you use Monolog a lot and have thoughts on what should change in the design, please open an issue! If you want to help grab one of those tasks (except those that aren't clear or still need to be decided on) and send a pull request! It's a great chance to play with PHP 7 features if you haven't yet. I took care of some things already but there is plenty more to be done and I definitely can't do it alone.

A word of caution

Please check your composer.json, if you require monolog/monolog dev-master you will have issues next time you update! Please fix that immediately and use ^1.17 instead, it will ensure you don't upgrade to 2.0 accidentally.

Supporting the past

Obviously, not everyone will upgrade to PHP 7 immediately, and Monolog v2 will probably not be ready and stable for a few months, so Monolog 1 will still be maintained. I don't have a concrete date in mind of when the maintenance will stop, but it is anyway pretty stable so I don't think maintaining it will be a big deal.

There is now a 1.x branch where bug fixes and features applicable to both versions should go, and 1.x releases will be created from there in the future.

December 18, 2015 // News, PHP // Post a comment

New Composer Patterns

Here is a short update on some nice little features that have become available in the last year in Composer.

Checking dependencies for bad patterns

You may know about the composer validate command, but did you know about its new --with-dependencies / -A flag? It lets you validate both your project and all your dependencies at once!

This is quite nice to check if any of your dependencies has unsafe requirements like >= or similar issues. You can also combine it with --strict to make sure that any warning results in a failure exit code, so you can detect warnings in your CI builds for example by checking the command exit code.

Try it out: composer validate -A --strict

Referencing scripts to avoid duplication

You can now reference other scripts by name to avoid having to define the exact same script command in multiple places (e.g. post-update-cmd and post-install-cmd is a common pattern). See the docs for an example. This could be applied to the symfony standard composer.json for example. The referenced script can even be array of scripts!

Defining your target production environment in composer.json

The config.platform option lets you emulate which platform packages you have available on your prod environment. That way even if you have a more recent PHP version or are missing an extension locally for example, composer will always resolve packages assuming that you have the packages you declared installed.

Let's take a concrete example. If I am running PHP 5.6 in production but use PHP 7 to develop on my machine, I might end up installing a package that depends on PHP 7 and not notice the problem until I deploy and things break on the server. Obviously it is better to develop with the exact same versions to avoid any surprises but this isn't always practical and especially when working on open source libraries I think many don't use VMs but instead work with whatever PHP they have on their host system.

In Composer for example we want to guarantee that we at least work with php5.3, so we tell Composer to fake the PHP version to be 5.3.9 when running updates, no matter what PHP version you run it with. If we did not do this for example the symfony/console package we depend on would upgrade to v3, but as symfony/console v3 requires at least PHP 5.5 it does not happen thanks to the platform config.

Excluding paths from the optimized classmap

When you run composer dump-autoload -o to get an optimized autoloader, Composer scans all files and builds a huge classmap, even for packages that define autoload rules as psr-0 or psr-4. This is great but in some cases you have some classes in the psr-4 path that you actually don't want to be included in this optimized map. One typical example of this would be Symfony2 bundles that follow the best practices layout of having all sources at the root of the repo. In this case the psr-4 path is "" (repo root) and there is a Tests/ folder which contains the test classes. Obviously in production we don't want to include those test classes in the optimized class map as it is just a waste. Adding the second line here to the autoload config will make sure they are not included:

"autoload": {
    "psr-4": { "Nelmio\\CorsBundle\\": "" },
    "exclude-from-classmap": ["/Tests/"]
},

Requiring packages easily and safely

For quite a while now we have had the ability of running composer require some/package without specifying the version and Composer just figures out the best requirement for you. However this came with a catch, as it always picked the latest version available. This usually works but if the latest version requires a newer PHP version than what you have on your machine it would actually fail. I fixed that and it now looks at your PHP version (or config.platform.php value) to determine which is the best version to install. This is great because it enables package authors to require PHP 7 in their new package version for example and anyone using composer require will not accidentally get this newer version installed until they are ready and using PHP 7 themselves. More on that note soon!

I hope these tips helped bring a bit more attention to those cool new features we have added!

December 18, 2015 // News, PHP // Post a comment

Composer hosting improvements

Over the last two weekends I proceeded to upgrade the infrastructure behind packagist.org and getcomposer.org. There is now a lot more bandwidth and the DNS hosting was also migrated to DNSMadeEasy which should make it more stable on that front.

All in all this should result in faster composer updates which is great! I also took the chance to do a few upgrades on the config, which now includes the latest PHP/nginx versions as well as OCSP stapling directives. While looking at logs I also noticed the composer installer was not using gzip compression so I fixed that and now installing composer itself should be a bit faster too if you have the zip extension enabled.

While the whole change happened without packagist downtime, there were a few minor issues early last week with the composer homepage. Today I had to re-enable http (i.e. no-TLS) access to packagist.org as people are still relying on accessing it without the openssl extension. This is not great but the travis 5.3.3 builds are missing openssl so it's not realistic to require it, hopefully in a year or two when 5.3 is a thing of the past we can go full-TLS.

Also note that the GitHub hooks updating packages on packagist are also using http and not https so the hooks using the default domain (http://packagist.org - I sent them a PR to update it to https by default) were not properly updated in the last ~24hours. I am really sorry I missed that but there is not much I can do at this point except wait until next time a hook fires and those affected packages finally get updated.

Please get in touch on github if you spot anything else out of the ordinary (except faster updates;).

And finally a quick shout-out to our sponsors, if you haven't checked Toran Proxy out yet please do so as it allows me to pay for the hardware as well as get some time off work to focus on open source without it always being unpaid leave. Many thanks to all existing Toran customers for their support!

May 03, 2015 // News, PHP // Post a comment

Composer 1.0 alpha9

I tagged Composer's 1.0.0-alpha9 release yesterday and wanted to write down a more detailed update on the highlights of this release. It includes many changes as the last tag was almost one year old. You can also check the full changelog if you want more details.

Requiring packages from CLI just got easier

The require command now guesses the best version constraint for the latest stable release of the package you require, so if you know you need a package but don't know what the latest version is you can just use for example composer require monolog/monolog and it will guess and use a constraint like ~1.11. There is also a new remove command to easily remove dependencies from the CLI without having to touch json.

Installing dependencies on the wrong environment is now possible

The new --ignore-platform-reqs flag for the install and update commands lets you install dependencies even if you have the wrong php version or are missing one of the required php extensions. It's not really recommended but it can be useful sometimes if you want to run composer outside a VM for example and you only have the right extensions installed in the VM where you run the code.

You now get warnings when installing abandoned packages

A few months back Packagist got this feature allowing packages to be marked as abandoned. For example this php markdown fork is not maintained anymore as the original package is now on Packagist as well. Marking it as abandoned lets people know they should ideally not rely on it in new projects, and migrate away if possible. If you install this package Composer now warns about it: Package dflydev/markdown is abandoned, you should avoid using it. Use michelf/php-markdown instead.. This should make it easier to deprecate packages and let your users know about it.

Custom composer commands via scripts

Script handlers defined for a non-existing event are now registered as custom composer commands. So you can for example define a test handler with the command to run your test suite, and then use composer test to call it. All the binaries installed as dependencies like phpunit in this example are made available in the PATH before the command is executed so you can call them easily without using the vendor/bin/ prefix.

Autoloading tests and related files

The new autoload-dev section lets you define autoload rules that only apply when your package is installed in dev mode, much like require-dev. This is mainly useful to split off test autoload rules from the main autoload rules the users of your packages will need.

Performance improvements

In case you missed it last week, we gained a huge performance boost by disabling garbage collection when running the Composer dependency solver. This is great news for everyone but I wanted to stress once again that you probably should not disable GC in your scripts unless you have a very good reason to do so. PHP's GC isn't flawed per se but our use case just falls out of the use cases it's been designed for. Anthony Ferrara wrote a good round-up of the issue in case you want to learn more.

A note on supporting Composer maintenance

While many of the above features have been contributed by others, reviewing pull requests and checking on new issues every day does take a lot of my time. I launched Toran Proxy about six months ago to help me get some paid time to work on and maintain Composer and Packagist. Looking at the numbers now it seems about 20% of the time spent was paid for thanks to Toran Proxy customers. I want to thank you all for supporting me and I hope more people will join in! I will try to do updates like this one more regularly to highlight new features and developments in the Composer ecosystem.

December 08, 2014 // News, PHP // Post a comment

My view of PHP version adoption

PHP 5.3 has been out of maintenance for about three months now and it seems like it's time for the community to move on at last. Drupal8 will target 5.4. Symfony announced the results of a poll about which PHP version Symfony3 should target (TL;DR: 5.5 and 5.6 are preferred). And Pascal Martin released yesterday an update on his PHP usage stats based on scanning server headers.

Pascal's number are interesting but I believe they have a bias towards older PHP versions. I would argue that people configuring their servers properly are also those that tend to keep up to date with newer versions, and part of the best practices is to avoid publishing the software versions you are using (i.e. disable expose_php in php.ini). If I am correct here that means early adopters are mis-represented in those numbers.

In any case, I do have another biased dataset to present so here it comes! I looked in the packagist.org logs of the last fifty days for GET /packages.json which represents a composer update done by someone. Since Composer sends the PHP version it is running with in its User-Agent header, I can use that to see which PHP versions people are using Composer with. Of course this data set is probably biased towards development machine and CI servers and as such it should also be taken with a grain of salt.

PHP usage statistics

I have two datasets, from November 2013 and today, which shows the progression of various versions. Any version below 3% usage has been removed to keep things readable.

November 2013

All versions Grouped
Total 4112760   100.00% Total 4112760   100.00%
PHP 5.3.10 490350 11.92% PHP 5.4 2069021 50.31%
PHP 5.3.3 419871 10.21% PHP 5.3 1533073 37.28%
PHP 5.4.20 387450 9.42% PHP 5.5 510596 12.41%
PHP 5.4.4 274741 6.68%
PHP 5.4.9 198343 4.82%
PHP 5.4.16 180150 4.38%
PHP 5.4.19 167416 4.07%
PHP 5.5.3 166317 4.04%
PHP 5.4.17 160754 3.91%
PHP 5.4.21 144939 3.52%
PHP 5.3.26 131497 3.20%

November 2014

All versions Grouped
Total 11556916   100.00% Total 11556916   100.00%
PHP 5.5.9 2475970 21.42% PHP 5.5 5647892 48.87%
PHP 5.4.4 1022498 8.85% PHP 5.4 3305929 28.61%
PHP 5.5.17 678997 5.88% PHP 5.3 1716653 14.85%
PHP 5.5.16 529227 4.58% PHP 5.6 886260 7.67%
PHP 5.3.3 509101 4.41%
PHP 5.3.10 479750 4.15%
PHP 5.6.0 391633 3.39%

A few observations: 5.3 really is on the way out, 5.5 is now the major platform, 5.6 adoption is lagging behind last year's 5.5 adoption a little bit which is unfortunate but can perhaps be explained by the fact Ubuntu 14.04 ships with 5.5.9

PHP requirements in Packages

A second dataset I looked at is which versions are required by all the PHP packages present on packagist. I split it in two groups: those that required a given version at any point and those that require it in their current master version.

PHP Requirements - Anytime - November 2014

5.2 1204 4.23%
5.3 20780 72.94%
5.4 7953 27.92%
5.5 641 2.25%
5.6 44 0.15%

PHP Requirements - Current Master - November 2014

5.2 1019 3.58%
5.3 19334 67.86%
5.4 7523 26.41%
5.5 573 2.01%
5.6 41 0.14%

A few observations: almost 7% of packages that required 5.3 and 15% of those requiring 5.2 gave these up for higher requirements, that's pretty low but it's a start. 5.4 is getting a good foothold but 5.5/5.6 features are hardly used by OSS packages.

Conclusions

Again these numbers need to be taken with a grain of salt, but looking at the ecosystem from this perspective I would say PHP 5.3 can be safely dropped by most libraries and 5.5 sounds like a promising target!

November 13, 2014 // News, PHP // Post a comment

[1] 2 Older entries > Last page