rfc:magic-methods-signature

This is an old revision of the document!


PHP RFC: Ensure correct magic methods' signatures when typed

Introduction

This RFC is inspired by a bug report that lists magic methods in PHP that do not have any checks at all to their signature when typed.

However, this implementation is not as simple as just check for the methods' signatures, as this is a Backward Incompatible Change for those who have incorrect signatures over their codebases.

Nowadays, PHP already checks the signature for the following methods:

Motivation

PHP's Magic Methods is something that PHP provides allowing developers to track and act on specific changes of behavior of a certain class. Given that fact, the same should ensure that the end-users are using these methods consistently across different codebases.

Since the introduction of types in PHP 7.0, only the checks listed above (under “Introduction”) were introduced to make sure that developers are using PHP's magic methods correctly.

For PHP 8, this RFC aims to expand these checks.

Proposal

This RFC proposes to introduce the following signatures checks when magic methods are typed.

Important: only, and only if, any of the listed magic methods use type hints and/or return types, these checks will be performed. In case they don't have types declared, nothing specific will happen.

The proposal follows the Magic Methods documentation.

/** @return mixed */
Foo::__call(string $name, array $arguments);
 
/** @return mixed */
Foo::__callStatic(string $name, array $arguments);
 
Foo::__clone(): void;
 
Foo::__debugInfo(): array;
 
/** @return mixed */
Foo::__get(string $name);
 
Foo::__isset(string $name): bool;
 
Foo::__serialize(): array;
 
/** @param mixed $value */
Foo::__set(string $name, $value): void;
 
/** @return mixed */
Foo::__set_state(array $properties);
 
Foo::__sleep(): array;
 
Foo::__unserialize(array $data): void;
 
Foo::__unset(string $name): void;
 
Foo::__wakeup(): void;

Note: The __construct and __destruct methods won't suffer any change. They won't allow void as a return type given the fact that (almost) all languages, including PHP, have the concept of Constructors and Destructors “returning” something after their execution.

Backward Incompatible Changes

An important note here is that if one of the listed magic methods is directly called, and it has the wrong signatures, the error will be thrown regardless.

For example https://3v4l.org/CuTNm, after this RFC, the errors about incorrect signatures will be thrown.

To Magic Methods without types declared

None.

To Magic Methods with the wrong signatures

Magic methods' signatures not matching the ones listed above, an error will be thrown, a Fatal Error more specific, following the errors of the same kind that are placed today.

RFC Impact

Scraping the top 1000 Composer packages (using Nikita's script), the results show only 7 occurrences of not matching signatures.

Luckily, none of them is a problem as __call, __callStatic and __get do not have checks at this time.

Even with a mixed RFC that wouldn't be a problem, as a specific type can override it, by the Liskov Substitution Principle.

Future Scope

This RFC only aims to add checks for the methods' signatures but as a Future Scope, a runtime check of what is been returning in the methods could be added, same as

Proposed Voting Choices

Yes/No.

External resources

rfc/magic-methods-signature.1587945014.txt.gz · Last modified: 2020/04/26 23:50 by carusogabriel