rfc:scalar_type_hints

This is an old revision of the document!


PHP RFC: Scalar Type Hints

Introduction

This RFC proposes the addition of four type hints for scalar types: int, float, string and bool. These follow the same casting rules as used for internal functions (i.e. those defined by PHP extensions and written in native code).

Example

Let's say we have a PHP class that represents an ElePHPant. We put scalar type hints on our constructor arguments.

class ElePHPant {
    public $name, $age, $cuteness, $evil;
    public function __construct(string $name, int $age, float $cuteness, bool $evil) {
        $this->name = $name;
        $this->age = $age;
        $this->cuteness = $cuteness;
        $this->evil = $evil;
    }
}

We can then create a new instance like this, and it's valid since the parameter types exactly match:

$sara = new ElePHPant("Sara", 7, 0.99, FALSE);

We could also pass values that are convertible, just like with extension functions, like so:

$nelly = new ElePHPant(new 

''Stringable''

("7 years"), "0.9", "1"); // valid, types will be cast
$evan = new ElePHPant(1234, "9", 0.3, 0); // also valid, types will be cast

Not all values are convertible, however, so the following would error:

$foo = new ElePHPant([], new StdClass, fopen("data:text/plain,foobar"), NULL);

Background

PHP has had parameter type hints for class names since PHP 5.0,

array

s since PHP 5.1 and

callable

s since PHP 5.4. Unfortunately, PHP's scalar types haven't been hintable. This has meant that the signatures of functions which take scalar arguments lack type information, requiring workarounds such as docblocks to document the parameter types, and requiring programmers to validate or convert arguments manually.

Previous attempts at adding scalar type hints, such as the Scalar Type Hints with Casts RFC, have failed. In particular, that specific proposal was inconsistent with the type conversion rules used in other parts of the language. However, this RFC follows exactly the same conversion rules as (and shares the implementation used by) function defined by native code extensions, with the exception of the handling of

NULL

(see the Details section). Thus, it avoids the problem of inconsistency.

To quote Rasmus:

PHP is and should remain:
1) a pragmatic web-focused language
2) a loosely typed language
3) a language which caters to the skill-levels and platforms of a wide range of users

Input coming from the web, such as query string parameters or POST bodies, is likely to be in string form. By performing conversion from strings automatically, just as with existing extension functions, this RFC is in keeping with PHP being a web-focused language. By allowing conversion instead of requiring strict type matches, this RFC is in keeping with PHP being a loosely-typed language. Finally, by not forcing users to worry about type conversions, it keeps the language accessible to beginners, keeping PHP a language catering to all skill-levels. Therefore, I feel that this RFC keeps all three of these principles true.

No type hint for resources was included, to avoid preventing the future updating of extensions that currently use resources to use classes.

Details

Four new reserved words are introduced: int, float, string and bool (these were not previously reserved because casting is special-cased by the lexer). When they are used as type hints, internally the validation and conversion functions used by the Fast Parameter Parsing API are called. Thus, they exactly match the behaviour of zend_parse_parameters. The only exception to this is the handling of NULL: in order to be consistent with our existing type hints for classes, callables and arrays, NULL is not accepted by default, unless the parameter is explicitly given a default value of NULL. This would work well with the draft Declaring Nullable Types RFC.

Backward Incompatible Changes

int, float, string and bool become reserved words, which they weren't previously.

Proposed PHP Version(s)

This is proposed for the next PHP x, currently PHP 7.

RFC Impact

To Existing Extensions

ext/reflection will need to be updated in order to support type hint reflection for parameters. This hasn't yet been done.

Unaffected PHP Functionality

This doesn't affect the cast operators, although the patch makes (int) be lexed as (, T_INT_TYPE and ) for nicer error messages, while it was previously lexed as T_INT_CAST.

Open Issues

None currently.

Future Scope

If return types were added, such as with the Return Type Hinting RFC, scalar type hints should be supported. A possible matter of debate would be whether or not to allow conversions in that case, given that msome of the reasons cited for parameter type conversion may not be applicable.

Proposed Voting Choices

As this is a language change, this RFC requires a 2/3 majority to pass. It will be a Yes/No vote.

Patches and Tests

There is a working, but incomplete patch that has tests here: https://github.com/TazeTSchnitzel/php-src/compare/scalar_type_hints_2_electric_boogaloo

There is not yet a language specification patch.

Implementation

After the project is implemented, this section should contain

  1. the version(s) it was merged to
  2. a link to the git commit(s)
  3. a link to the PHP manual entry for the feature

References

Changelog

  • v0.1 - Initial draft
rfc/scalar_type_hints.1418527424.txt.gz · Last modified: 2017/09/22 13:28 (external edit)