What's new in PHP land? - Q4 2019
I co-organise the BrisPHP Meetup and at the start of every meetup I give a quick talk on recent news and other interesting things that have been happening in the PHP world. Recently, we’ve had some security vulnerabilities, a few cool projects in the community and more features accepted into PHP 8.0.
PHP
PHP 7.4
There are no new features going into PHP 7.4, and for very good reason. It’s going to be released at the end of this month!
I can’t wait for the new version, my favourite new features are:
- Typed properties
- Preloading
- Arrow functions
See my previous posts for more info on these and other new features:
PHP 8.0
There have been two new features accepted in PHP 8.0 this quarter.
Union types
The Union Types 2.0 RFC brings forward the idea of union types, or typing a variable to be one of two or more different types. You can use union types everywhere that existing types are currently accepted.
DISCLAIMER: At the time of writing this one still had a few days left of voting. However, an overwhelming majority of votes are in favour so I’ll risk it for the biscuit and call it.
Example:
<?php
class Number {
private int|float $number;
public function setNumber(int|float $number): void {
$this->number = $number;
}
public function getNumber(): int|float {
return $this->number;
}
}
We already have a union type in order to allow for nullables. So ?int
and int|null
will be equivalent. But you will not be able to use the question mark when there are
multiple possible types. For example ?int|float
is invalid.
Additionally, an false
psuedo type is being added to account for the many
places in the core that a function returns false
on error. For example
strpos()
can be typed as int|false
. Note that false
cannot be typed on
it’s own, it must be part of a union type.
Reclassifying engine warnings
Nikita Popov suggested we should increase the error level for some internal warnings and notices because they represent bad programming errors. There were 23 changes proposed, of which 3 were voted on separately because they were controversial, while the remaining 20 were voted on as one. See the RFC for the full list of reclassifications, I’ll list the controversion ones here:
- Undefined variables
- Being promoted from a Notice to a Warning
- Attempt was made to get it as an Error exception, but it did not have enough votes
- Undefined array index
- Being promoted from a Notice to a Warning
- Division by zero
- Being promoted from a Warning to a DivisionByZeroError exception
There were 20 non-controversial changes proposed:
- Promoting 8 Warnings to Error exceptions
- Promoting 7 Notices to Warnings
- Promoting 5 Warnings to TypeError exceptions
P++
The idea was floated in the internal mailing list about creating a second “dialect” of PHP with some suggesting the name “P++”. The idea was to have the same PHP engine running both the normal version of PHP and a strict type-safe version. It was raised because there has been a lot of internal discussion about whether or not PHP should become more strict moving forward, for which there are almost equal amounts of people for and against.
In the end, the idea was withdrawn after considerable discussion both internally and from many randoms on the internet. With the outcome being that PHP would slowly introduce more strict features by making them optional.
Security vulnerabilities
RCE through open php-fpm ports
If you have php-fpm configured to listen on a TCP port, and that port is exposed to the world, at attacker can trick php-fpm in executing an arbitrary php file on the system. As such, you should follow best practices and hide php-fpm behind a webserver such as nginx. See the bug report here.
Buffer overflow
PHP 7.3.10 fixed a heap buffer overflow vulnerability in the mb_eregi()
function which could grant an attacker arbitrary code execution.
A post by SC Magazine
has more details.
RCE through PATH_INO in php-fpm
With a mis-configured php-fpm, it was possible to use a newline character (url encoded %0a
)
to break the PATH_INFO variable that nginx passes to php-fpm by unsetting it. This caused
php-fpm to read a different php file and if crafted properly could allow remote code execution.
The “mis-configuration” of php-fpm is actually a fairly widely used configuration, documented in many places like StackOverflow and even the nginx docs. To fix the issue you can upgrade to the latest version of PHP or add some sanitisation to your nginx configuration.
See the bug report for more info.
Frameworks
Wordpress
Wordpress is talking about strictly enforcing SSL for auto updates. From what I can gather, getting either core WordPress updates or plugin/theme updates doesn’t necessarily happen over SSL at the moment, so they want to enforce it and also add checksum validation to enforce packgage integrity. While I think this should already have been a thing, I’m glad to see WordPress pushing forward on security.
Slim 4.0
Slim 4.0 was released in August and it has a bunch of changes to push the framework forward:
- Decoupling a lot of dependencies so you’re not forced to install them
- Dependency injection
- Router
- Error handling
- PSR-7
- Only supports PHP 7.1+
- Removed a few “automagic” abilities to make the framework easier to understand
Symfony 5.0
Symofony 5.0 is due to be released this month along with 4.4. The 4.4 version will contain all the features for 5.0 with backward compatibility and a bunch of deprecations. This gives you an easy upgrade path because once you remove deprecations, your app will function perfectly on 5.0.
There aren’t as many groundbreaking features in 5.0 as there was in 4.0, but there’s a nice list of them here. My favourites are:
- Encrypted secrets management which allows you to store secrets in the git repo (eg. database passwords).
- Automatic password migrations to automatically rehash users passwords with the latest algorithm.
- Testing email content allows to assert email bodies contain specific content.
Community
Client side PHP
Atymic has found a way to run PHP in the browser. This may seem a little insane, and it is. Because you need to:
- Download PHP source
- Build your app into a .phar
- Complile your .phar and PHP source using web assembly
- Make your users load this and run it
While this terrifies me, it also excites me that we’re still pushing the boundaries of PHP can (or even should) do.
Dependency graph support on GitHub
GitHub can now hook into your composer.json to give you automatic security notifications/updates as well as insights into your dependency tree.