PHP Annotated — May 2021

PHP Annotated Monthly
Greetings everyone!

PHP 8.0 is gaining momentum and adoption is increasing, as evidenced by Composer’s statistics.

Meanwhile, PHP internals have accepted a bunch of changes for PHP 8.1, including a new never type and namespaces in bundled PHP extensions, and some features that will be deprecated.

The PHP 8.1 release managers have been selected, and there are several interesting proposals under discussion, including property accessors, pure intersection types, and final constants.

Read more about this news in the May edition of PHP Annotated. As usual, we’ve carefully selected a collection of articles, tools, videos, and streams for you.

⚡️ News

  • PHP Versions Stats – 2021.1

    The traditional compilation of statistics based on the data that Composer sends when it connects to packagist.org:

    • PHP 7.4: 45.92% (+3.31)
    • PHP 7.3: 21.30% (-5.75)
    • PHP 7.2: 12.89% (-2.39)
    • PHP 8.0: 9.44% (+9.17)
    • PHP 7.1: 5.21% (-2.24)
  • PHP is available on Google Cloud Functions

    Google Cloud’s serverless platform now natively supports PHP. With GoogleCloudPlatform/functions-framework-php/ you can run functions in a PHP 7.4-based runtime.

    There are a few more details in the discussion on GitHub in the Symfony repository. Symfony 5.3 should run on GCF smoothly, thanks to the Runtime component. You just need to install php-runtime/google-cloud.

  • Composer Command Injection Vulnerability

    The vulnerability in Composer only affects systems that have Mercurial installed. However, it is worth immediately updating to versions 2.0.13 and 1.10.22, which contain fixes. Check out a more detailed technical analysis of the vulnerability.

  • Follow up on git.php.net attack

    Attackers pushed two commits to the PHP source on behalf of Rasmus Lerdorf and Nikita Popov. The problem was quickly detected and solved. The malicious code did not get to users.

    As it turned out, the git.php.net server allowed commits via HTTPS and used digest authentication, which accepts md5 hash as a secret. The hash database of all the contributors was obtained by the attackers from master.php.net, which was probably the server that was originally compromised.

    As a result, all development has been fully moved to GitHub, which makes life easier for language developers.

  • PHP 7.4.19, PHP 8.0.6 – With a fix in PDO_pgsql.

🐘 PHP Internals

  • [RFC] never type

    PHP 8.1 will have a new type for returned values: never.

    A function or method declared with the never type indicates that it will never return a value, and it either throws an exception or terminates with a call of type die(), exit(), trigger_error().

    It is an empty bottom type and is a subtype of all other types, and there are similar types in Python, Rust, Kotlin, and TypeScript. This type improves static analysis.

    function redirect(string $uri): noreturn {
        header('Location: ' . $uri);
        exit();
    }
    
    function redirectToLoginPage(): noreturn {
        redirect('/login');
    }

    You can find more details on PHP.Watch or listen to the PHP Internals News podcast with Matt Brown and Ondřej Mirtes.

  • [RFC] Deprecate implicit non-integer-compatible float to int conversions

    In PHP 8.1, an E_DEPRECATED notice will be thrown when float is converted into int and fractional part is lost. Later, in PHP 9.0, this will cause a TypeError.

    function acceptInt(int $i) {
            var_dump($i);
    }
    acceptInt(3.1415);
    
    > int(3) // Deprecation notice

    Learn more from the 🔈 PHP Internals News podcast #83 with George Peter Banyard.

  • [RFC] Phasing out Serializable

    In PHP 8.1 the Serializable interface will be deprecated. A deprecation notice will be thrown when the class uses only this interface, that is, if the class does not additionally have the new magic methods __serialize() and __unserialize().

  • [RFC] Namespaces in bundled PHP extensions

    This marks a small step towards cleaner PHP! New symbols (classes, interfaces, etc.) in extensions will now have to use namespaces.

    Here’s an example. The resource type is de-facto obsolete in PHP, and all existing resources are slowly being migrated to objects. In PHP 8.1 some resources will be replaced with the following namespaced classes:

    IMAPConnection -> IMAP\Connection
    FTPConnection -> FTP\Connection
    LDAP -> LDAP\Connection
    LDAPResult -> LDAP\Result
    LDAPResultEntry -> LDAP\ResultEntry
    PgSql -> PgSql\Connection
    PgSqlResult -> PgSql\Result
    PgSqlLob -> PgSql\Lob
  • [RFC] Add return type declarations for internal methods

    Most of the built-in methods in PHP 8.0 have received parameters and return type declarations. In some cases, however, this could not be done, like for the return values of public non-final methods. The problem is that they can be overridden in user code.

    Here is an example to illustrate the problem
    class SomeStandardClass
    {
        public function method(): int {}
    }
    
    class UserClass extends SomeStandardClass
    {
        public function method() {}
    }
    
    // Fatal error: Declaration of UserClass::method() must be compatible with SomeStandardClass::method()
    

    There will now be a gradual migration for such cases. In PHP 8.1, all internal methods will also get the missing types. If they are overridden in user code, a Deprecation notice will be thrown.

    class MyDateTime extends DateTime
    {
        public function modify(string $modifier) { return false; }
    }
    
    // Deprecated: Declaration of MyDateTime::modify(string $modifier) should be compatible with DateTime::modify(string $modifier): DateTime|false
    
  • Release managers for PHP 8.1 have been selected

    There will be three managers this time around: the experienced Joe Watkins (pthreads, parallel, pcov), and two newcomers, Patrick Allaert (blackfire.io) and Ben Ramsey (ramsey/uuid). Check PHP Internals News podcast #84 with Ben and Patrick.


    New proposals for PHP 8.1:

  • [RFC] Partial Function Application

    Partial function application (partial functions) is when only some arguments are bound on function call, and the others remain as parameters to be passed later.

    For example, here is a full function:

    function whole($one, $two) {
        /* ... */
    }

    And here’s a partial one based on it:

    $partial = whole(?, 2);

    In this case, the partial signature will look like this:

    function($one) {
        /* ... */
    }

    Why is this needed?

    Firstly, you can now get a reference to any function or method and pass it wherever Callable is expected. For example, you could do this

    array_map(Something::toString(?), [1, 2, 3]);
    array_map(strval(?), [1, 2, 3]);
    
    // instead of
    array_map([Something::class, 'toString'], [1, 2, 3])
    array_map('strval', [1, 2, 3]);

    And secondly, as a consequence, it will be possible to implement the pipe operator |>:

    $result = "Hello World"
        |> htmlentities(?)
        |> explode(?);

    See it in action at 3v4l.org.

    Thanks to Larry Garfield, Joe Watkins, Levi Morrison, and Paul Crovella for the RFC and the implementation.

  • [RFC] Property Accessors

    Nikita has finalized the implementation of the property accessors, and the proposal is now officially under discussion.

    The bottom line is that traditional getters and setters are not convenient to use, and the magic methods __get and __set are not specific. The new accessors are meant to fix these issues.

    The syntax is inspired by C#:

    class Foo {
        public $prop {
            get { /* ... */ }
            set { /* ... */ }
        }
    }
    

    You can use them to implement read-only properties:

    class User {
        public string $name { get; }
    
        public function __construct(string $name) {
            $this->name = $name;
        }
    }
    

    And you can specify asymmetric access, i.e. make them public or private separately for reading and writing:

    class User {
        public string $name { get; private set; }
    
        ...
    }
    

    Or you can use them as full-fledged methods for validation or other actions:

    class Foo {
        public int $bar {
            get {
                error_log('Getting $bar');
                return $this->bar;
            }
            set {
                assert($bar > 42);
                $this->bar = $bar;
            }
        }
    }
    
  • [RFC] Pure intersection types

    Union types were added in PHP 8.0, and this RFC proposes to add intersection types.

    The syntax is TypeA&TypeB, and it means that the variable must be both instanceof TypeA and instanceof TypeB.

    Details
    class A {
        private Traversable&Countable $countableIterator;
    
        public function setIterator(Traversable&Countable $countableIterator): void {
            $this->countableIterator = $countableIterator;
        }
    
        public function getIterator(): Traversable&Countable {
            return $this->countableIterator;
        }
    }
    

    The proposal is called “pure intersection types” because combinations with union types are not supported and are being left for future consideration. Aliases for complex types are also being left for the future.

  • [RFC] Deprecate ticks

    There is a tick mechanism in PHP: declare(ticks=1). It was originally needed to track pcntl signals. Now you can use pcntl_signal() and pcntl_async_signals() for this, which is why there’s been a suggestion to deprecate ticks in PHP 8.1 and remove them completely in PHP 9.

  • [RFC] Final class constants

    The author of this RFC proposes a final modifier for constants, so that they cannot be overridden in child classes.

    Details
    class Foo
    {
        final public const X = "foo";
    }
    
    class Bar extends Foo
    {
        public const X = "bar";
    }
    
    // Fatal error: Bar::X cannot override final constant Foo::X
    

    Fun fact from RFC: constants in interfaces are already final.

  • A couple more links for those who would like to start contributing to PHP source:

🛠 Tools

Symfony

Laravel

Yii

PhpStorm

💡 Misc

📺 Videos

🔈 Podcasts

🙌 Community

  • PHP’s bus factor is 2 – Joe Watkins says that only two people know enough about the PHP source, so we should consider this when thinking about adding new features to PHP. He also says that we need more developers working on the core.

Thanks for reading!

If you have any interesting or useful links to share via PHP Annotated, please leave a comment on this post or send me a tweet.

Subscribe to PHP Annotated

Your JetBrains PhpStorm team
The Drive to Develop

image description