Release Announcement
This is a new-feature release, where backward incompatibilities are mainly restricted to not being quite as carefree about programmer silliness (trying to address an array element of an integer will generate a notice). The embedded MySQLi server has been removed (remember the embedded MySQLi server? Neither did anyone else. Which is why no-one used it. No wonder it went so long without it actually working.)

More fun to talk about are the new features.

  • a new FFI extension that provides a runtime mapping directly between PHP code and external shared/dynamic libraries. This one's still experimental, but it's nice that PHP is now able to talk to other programs this way.

  • Object properties can have types assigned to them:

    protected int $someinteger;
  • better support in type declarations; some (co|contra)variance support in declaring return/parameter types of methods in subclasses.

       interface Base {}
       interface Derived extends Base {}
       
    class ParentClass { public function doStuff(): Base{/* */}} class ChildClass extends ParentClass { public function doStuff(): Derived{/* */}}

    Previously, ChildClass::doStuff() would have had to have been declared as returning an instance of Base because that's what its parent class said, even though it would only ever return Derived; that loss of discrimination limited how much could be said later on if you wanted to restrict an input type to Derived.

  • a ??= operator that serves to set a variable to a given value only if the variable doesn't have a value already:

    $input['field'] ??= $defaultField;

    instead of

    if(!isset($input['field'])) $input['field'] = $defaultField;

    As well as being tidier and more quickly read, the new syntax means identifying the variable only has to be done once.

  • the ... can be used inside array literals to interpolate other arrays:

    $inner = [1, 2, 3, 4];
    $more = ["foo", "bar", ...$inner, "baz"];
    echo '[' . join(", ", $more) . ']'; // [foo, bar, 1, 2, 3, 4, baz]
  • numeric literals can have embedded _ just to make them easier to read in code (especially helpful when writing numbers in binary)

    $mask = 0b0000_1010_0000;

    instead of

    $mask = 0b000010100000;

    or

    $mask = 0xa0;
  • a less-quirky method for whitelisting tags in strip_tags;

    strip_tags($input, ['a', 'b']);

    instead of

    strip_tags($input, '<a><b>');
  • the new fn keyword has been added to allow a more streamlined syntax for single-statement inline functions;

    $maxlength = 76;
    $truncated_lines = array_map(fn($line) => substr($line, 0, $maxlength), $lines);

    instead of

    $maxlength = 76;
    $truncated_lines = array_map(function($line)use($maxlength) {
        return substr($line, 0, $maxlength);
    }, $lines);

There is a lot more than just these, of course. The release announcement is at the top of this post; for the manual's take, see Migrating from PHP 7.3.x to PHP 7.4.x.

4 years later
Write a Reply...