https://www.php.net/releases/8.1/en.php

First point release of PHP v8 keeps mainly backwards-compatibility of course, as befitting a point release. Most of the incompatibilities that are there are a result of making things work more the way you'd expect.

New features are much more fun. The biggy — significant enough on its own but even moreso in combination with 8.0's match statement — is enum. PHP now has first-class enumerations:

enum WarningLevel {
    case Panic;
    case Error;
    case Warning;
    case Info;
    case Debug;
    }

letting you assign a proper WarningLevel type declaration in function signatures instead of declaring a string and checking values inside the function, or — if you wanted type safety — a bunch of do-nothing instances of do-nothing classes that exist solely to implement some do-nothing interface solely for the sake of being able to use that interface as a type declaration (sound confusing? that's why enums).

More stuff:

  • Class constants can be declared final so that subclasses are prevented from overriding them.
  • Default arguments, static variables, and global constants can now be objects (you can, for example, declare a method's parameter to have a default value of "new Dependency" instead of some workaround like "default to null and then check in the method body for that and use 'new Dependency' if null is found")
  • any callable can be turned into a Closure object (okay, you could already do that with Closure::fromCallable but now there's specific syntax for it: callable(...))
  • readonly properties, because sometimes you don't want a property to be modifiable, but you want it to vary by instance and constants by definition don't.
  • Fibres: primitives for building libraries to do asynchronous and other concurrent processing
    3 months later

    This item I didn't pay that much attention to first time around:

    • any callable can be turned into a Closure object (okay, you could already do that with Closure::fromCallable but now there's specific syntax for it)

    That goes for any callable, including plain strings and arrays that are supposed to be the names of functions.

    array_map('somefn', $array)

    can be written

    array_map(somefn(...), $array)

    and

    array_map([$object, 'method'], $array)

    becomes the much more intuitive-looking

    array_map($object->method(...), $array)

    And they're still first-class values:

    $mapping = $object->method(...);
    $mapped = array_map($mapping, $array);

    That last point makes them even better than string or array callables. Which function gets used when a string/array callable is used depends on what is in scope at that moment; which methods are visible, which namespaces are in use, and so on. While most callbacks get created and used almost immediately, it's perfectly reasonable to want to pass them around to other functions, and entirely possible to create a callback that isn't actually callable at all because there is no function anywhere with a matching name: it won't be checked until you try to actually use it.

    All of those might be different from when the callable was defined, and the one that's picked may not be the one that was intended (there may not even be a suitable candidate available).

    Creating a first-class Closure object instead means that the name is bound to the relevant function at the time the object is created: much more consistent, and you're told sooner if there is a problem with the name you're trying to use.

      2 years later
      Write a Reply...