From b3609ef4a8d6566d0e5733cb03b01e9ec18be082 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Denis=20=C5=BDoljom?= Date: Fri, 12 Aug 2022 17:05:56 +0200 Subject: [PATCH] Add type declarations chapter --- wordpress-coding-standards/php.md | 121 +++++++++++++++++++++--------- 1 file changed, 85 insertions(+), 36 deletions(-) diff --git a/wordpress-coding-standards/php.md b/wordpress-coding-standards/php.md index 8b5085b..1e8af5e 100644 --- a/wordpress-coding-standards/php.md +++ b/wordpress-coding-standards/php.md @@ -409,6 +409,91 @@ class Foo { } ``` +### Type declarations + +[alert] +Type declaration usage has the following restrictions based on the minimum required PHP version: + +- The scalar `bool`, `int`, `float`, and `string` type declarations cannot be used until the minimum PHP version is PHP 7.0 or higher. +- Return type declarations cannot be used until the minimum PHP version is PHP 7.0 or higher. +- Nullable type declarations cannot be used until the minimum PHP version is PHP 7.1 or higher. +- The `iterable` and `void` type declarations cannot be used until the minimum PHP version is PHP 7.1 or higher. The `void` can only be used as a return type. +- The `object` type declaration cannot be used until the minimum PHP version is PHP 7.2 or higher. +- Property type declarations cannot be used until the minimum PHP version is PHP 7.4 or higher. +- `static` return type cannot be used until the minimum PHP version is PHP 8 or higher. +- `mixed` type cannot be used until the minimum PHP version is PHP 8 or higher. Because `mixed` type includes `null`. it's not allowed to make it nullable. +- Union types cannot be used until the minimum PHP version is PHP 8 or higher. +- Intersection types cannot be used until the minimum PHP version is PHP 8.1 or higher. +- `never` return type cannot be used until the minimum PHP version is PHP 8.1 or higher. +[/alert] + +Type declarations must have exactly one space before and after the type. The nullability operator (`?`) is regarded as part of the type declaration and there should be no space between this operator and the actual type. Class/interface name based type declarations should use the case of the class/interface name as declared, while the keyword-based type declarations should be lowercased. + +Return type declarations should have no space between the closing parenthesis of the function declaration and the colon starting a return type. + +These rules apply to all structures allowing for type declarations: functions, closures, catch conditions as well as the PHP 7.4 arrow functions and typed properties. + +The following examples showcase what type hints are currently available in the WordPress Core due to the minimum supported PHP version + +```php +// Correct. +function foo( Class_Name $parameter, callable $callable, array $number_of_things = [] ) { + // Do something. +} + +function bar( + Interface_Name $param_a, + array $param_b, + callable $param_c = 'default_callable' +) { + // Do something. +} + +// Incorrect. +function baz(Class_Name $param_a, String$param_b, CALLABLE $param_c ) { + // Do something. +} +``` + +The following examples showcase what you can use in your themes and plugins if you require specific minimum PHP version (7.4 for instance) + +```php +// Correct. +function foo( Class_Name $param_a, ?string $param_b, callable $param_c ): ?\Class_Name { + // Do something. +} + +function bar( + Interface_Name $param_a, + ?int $param_b, + bool $param_c +): iterable { + // Do something. +} + +// Incorrect. +function baz(Class_Name $param_a, ? Float$param_b, CALLABLE $param_c ) : ? \Class_Name{ + // Do something. +} +``` + +_Usage in WordPress Core_ + +[warning] +Adding type declarations to existing WordPress Core functions should be done with extreme care. +[/warning] + +While rare, `array` and class/interface name based type declarations already exist in WordPress Core. + +The function signature of any function (method) which can be overloaded by plugins or themes should not be touched. +This includes all existing `public` and `protected` class methods and any conditionally declared (pluggable) functions in the global namespace. + +This leaves, for now, only unconditionally declared functions in the global namespace, `private` class methods, and code newly being introduced as candidates for adding type declarations. + +For those, adding `callable`, class and interface name based parameter type declarations where the parameter type only expects one type and it would allow for simplification of existing/new code, is allowed and tentatively encouraged. + +Using the `array` keyword in type declarations is **strongly discouraged** for now, as most often, it would be better to use `iterable` to allow for more flexibility in the implementation and that keyword is not yet available for use in WordPress Core until the minimum requirements are raised to PHP 7.1. + ## Declare Statements, Namespace, and Import Statements ### Namespace declarations @@ -543,42 +628,6 @@ $foo = new \Vendor // Source: external dependency. $result = namespace \function_name(); // Notice the space between namespace and \function_name(). ``` -### Using fully qualified names in inline code - -When using a fully or partially qualified name, no whitespace or comments are allowed within the name. - -```php -// Correct. -$foo = new \Vendor\Domain\Foo(); - -$result = namespace\function_name(); - -// Incorrect. -$foo = new \Vendor // Source: external dependency. - \Domain - \Foo(); - -$result = namespace \function_name(); // Notice the space between namespace and \function_name(). -``` - -### Using fully qualified names in inline code - -When using a fully or partially qualified name, no whitespace or comments are allowed within the name. - -```php -// Correct. -$foo = new \Vendor\Domain\Foo(); - -$result = namespace\function_name(); - -// Incorrect. -$foo = new \Vendor // Source: external dependency. - \Domain - \Foo(); - -$result = namespace \function_name(); // Notice the space between namespace and \function_name(). -``` - ## Object-Oriented Programming ### Only One Object Structure (Class/Interface/Trait) per File