GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Downloads
  • Documentation
  • Get Involved
  • Help
  • Getting Started
  • Introduction
  • A simple tutorial
  • Language Reference
  • Basic syntax
  • Types
  • Variables
  • Constants
  • Expressions
  • Operators

This view

  • Original page
  • New address

GeezerVison is showing www.php.net — PHP: PHP 8.1.0 Release Announcement

PHP 8.6.0 RC5 available for testing

    Released!

    PHP 8.1 is a major update of the PHP language.
    It contains many new features, including enums, readonly properties, first-class callable syntax, fibers, intersection types, performance improvements and more.

    Upgrade to PHP 8.1 now!

    Enumerations

    Use an enum instead of a set of constants to get validation out of the box.

    PHP < 8.1
    class Status
    {
        const DRAFT = 'draft';
        const PUBLISHED = 'published';
        const ARCHIVED = 'archived';
    }
    function acceptStatus(string $status) {...}
    PHP 8.1 RFC ↗ Doc ↗
    enum Status
    {
        case Draft;
        case Published;
        case Archived;
    }
    function acceptStatus(Status $status) {...}

    Readonly Properties

    Readonly properties cannot be changed after initialization, i.e. after a value is assigned to them.
    They are a great way to model value objects and data-transfer objects.

    PHP < 8.1
    class BlogData
    {
        private Status $status;
    
        public function __construct(Status $status)
        {
            $this->status = $status;
        }
    
        public function getStatus(): Status
        {
            return $this->status;
        }
    }
    PHP 8.1 RFC ↗ Doc ↗
    class BlogData
    {
        public readonly Status $status;
    
        public function __construct(Status $status)
        {
            $this->status = $status;
        }
    }

    First-class Callable Syntax

    It is now possible to get a reference to any function – this is called first-class callable syntax.

    PHP < 8.1
    $foo = [$this, 'foo'];
    
    $fn = Closure::fromCallable('strlen');
    PHP 8.1 RFC ↗ Doc ↗
    $foo = $this->foo(...);
    
    $fn = strlen(...);

    New in initializers

    Objects can now be used as default parameter values, static variables, and global constants, as well as in attribute arguments.

    This effectively makes it possible to use nested attributes.

    PHP < 8.1
    class Service
    {
        private Logger $logger;
    
        public function __construct(
            ?Logger $logger = null,
        ) {
            $this->logger = $logger ?? new NullLogger();
        }
    }
    PHP 8.1 RFC ↗
    class Service
    {
        private Logger $logger;
    
        public function __construct(
            Logger $logger = new NullLogger(),
        ) {
            $this->logger = $logger;
        }
    }
    PHP < 8.1
    class User
    {
        /**
         * @Assert\All({
         *     @Assert\NotNull,
         *     @Assert\Length(min=5)
         * })
         */
        public string $name = '';
    }
    PHP 8.1
    class User
    {
        #[\Assert\All(
            new \Assert\NotNull,
            new \Assert\Length(min: 5))
        ]
        public string $name = '';
    }

    Pure Intersection Types

    Use intersection types when a value needs to satisfy multiple type constraints at the same time.

    It is not currently possible to mix intersection and union types together such as A&B|C.

    PHP < 8.1
    function count_and_iterate(Iterator $value) {
        if (!($value instanceof Countable)) {
            throw new TypeError('value must be Countable');
        }
    
        foreach ($value as $val) {
            echo $val;
        }
    
        count($value);
    }
    PHP 8.1 RFC ↗ Doc ↗
    function count_and_iterate(Iterator&Countable $value) {
        foreach ($value as $val) {
            echo $val;
        }
    
        count($value);
    }

    Never return type

    A function or method declared with the never type indicates that it will not return a value and will either throw an exception or end the script’s execution with a call of die(), exit(), trigger_error(), or something similar.

    PHP < 8.1
    function redirect(string $uri) {
        header('Location: ' . $uri);
        exit();
    }
    
    function redirectToLoginPage() {
        redirect('/login');
        echo 'Hello'; // <- dead code
    }
    PHP 8.1 RFC ↗ Doc ↗
    function redirect(string $uri): never {
        header('Location: ' . $uri);
        exit();
    }
    
    function redirectToLoginPage(): never {
        redirect('/login');
        echo 'Hello'; // <- dead code detected by static analysis
    }

    Final class constants

    It is possible to declare final class constants, so that they cannot be overridden in child classes.

    PHP < 8.1
    class Foo
    {
        public const XX = "foo";
    }
    
    class Bar extends Foo
    {
        public const XX = "bar"; // No error
    }
    PHP 8.1 RFC ↗ Doc ↗
    class Foo
    {
        final public const XX = "foo";
    }
    
    class Bar extends Foo
    {
        public const XX = "bar"; // Fatal error
    }

    Explicit Octal numeral notation

    It is now possible to write octal numbers with the explicit 0o prefix.

    PHP < 8.1
    016 === 16; // false because `016` is octal for `14` and it's confusing
    016 === 14; // true
    PHP 8.1 RFC ↗ Doc ↗
    0o16 === 16; // false — not confusing with explicit notation
    0o16 === 14; // true

    Fibers

    Fibers are primitives for implementing lightweight cooperative concurrency. They are a means of creating code blocks that can be paused and resumed like Generators, but from anywhere in the stack. Fibers themselves don't magically provide concurrency, there still needs to be an event loop. However, they allow blocking and non-blocking implementations to share the same API.

    Fibers allow getting rid of the boilerplate code previously seen with Promise::then() or Generator based coroutines. Libraries will generally build further abstractions around Fibers, so there's no need to interact with them directly.

    PHP < 8.1
    $httpClient->request('https://example.com/')
            ->then(function (Response $response) {
                return $response->getBody()->buffer();
            })
            ->then(function (string $responseBody) {
                print json_decode($responseBody)['code'];
            });
    PHP 8.1 RFC ↗ Doc ↗
    $response = $httpClient->request('https://example.com/');
    print json_decode($response->getBody()->buffer())['code'];

    Array unpacking support for string-keyed arrays

    PHP supported unpacking inside arrays through the spread operator before, but only if the arrays had integer keys. Now it is possible to unpack arrays with string keys too.

    PHP < 8.1
    $arrayA = ['a' => 1];
    $arrayB = ['b' => 2];
    
    $result = array_merge(['a' => 0], $arrayA, $arrayB);
    
    // ['a' => 1, 'b' => 2]
    PHP 8.1 RFC ↗ Doc ↗
    $arrayA = ['a' => 1];
    $arrayB = ['b' => 2];
    
    $result = ['a' => 0, ...$arrayA, ...$arrayB];
    
    // ['a' => 1, 'b' => 2]

    Performance Improvements

    Symfony Demo App request time
    25 consecutive runs, 250 requests (sec)
    (less is better)

    The result (relative to PHP 8.0):

    • 23.0% Symfony Demo speedup
    • 3.5% WordPress speedup

    Performance related features in PHP 8.1:

    • JIT backend for ARM64 (AArch64)
    • Inheritance cache (avoid relinking classes in each request)
    • Fast class name resolution (avoid lowercasing and hash lookup)
    • timelib and ext/date performance improvements
    • SPL file-system iterators improvements
    • serialize/unserialize optimizations
    • Some internal functions optimization (get_declared_classes(), explode(), strtr(), strnatcmp(), dechex())
    • JIT improvements and fixes

    New Classes, Interfaces, and Functions

    • New #[ReturnTypeWillChange] attribute.
    • New fsync and fdatasync functions.
    • New array_is_list function.
    • New Sodium XChaCha20 functions.

    Deprecations and backward compatibility breaks

    • Passing null to non-nullable internal function parameters is deprecated.
    • Tentative return types in PHP built-in class methods
    • Serializable interface deprecated.
    • HTML entity en/decode functions process single quotes and substitute by default.
    • $GLOBALS variable restrictions.
    • MySQLi: Default error mode set to exceptions.
    • Implicit incompatible float to int conversion is deprecated.
    • finfo Extension: file_info resources migrated to existing finfo objects.
    • IMAP: imap resources migrated to IMAP\Connection class objects.
    • FTP Extension: Connection resources migrated to FTP\Connection class objects.
    • GD Extension: Font identifiers migrated to GdFont class objects.
    • LDAP: resources migrated to LDAP\Connection, LDAP\Result, and LDAP\ResultEntry objects.
    • PostgreSQL: resources migrated to PgSql\Connection, PgSql\Result, and PgSql\Lob objects.
    • Pspell: pspell, pspell config resources migrated to PSpell\Dictionary, PSpell\Config class objects.

    Better performance, better syntax, improved type safety.

    Upgrade to PHP 8.1 now!

    For source downloads of PHP 8.1 please visit the downloads page. Windows binaries can be found on the PHP for Windows site. The list of changes is recorded in the ChangeLog.

    The migration guide is available in the PHP Manual. Please consult it for a detailed list of new features and backward-incompatible changes.

    You are visitor 01402503 — GeezerVison does not store the pages you look up.
    Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.