Detailed example code for PHP7 scalar type declaration RFC

Source: Internet
Author: User
Tags rfc scalar

First, summary

The RFC recommends adding 4 new scalar type declarations: int,float,string and bool, which will be used in a consistent way with the original PHP mechanism. RFCs are recommended for each PHP file, adding a new optional directive (declare (strict_type=1)), so that all function calls and statements within the same PHP file are returned with a "strictly constrained" scalar type declaration check. In addition, when a strict type constraint is turned on, the call extension or PHP built-in function fails to parse the parameter, resulting in a e_recoverable_error-level error. With these two features, the RFC wants to write PHP to be more accurate and document-based.

Second, details

Scalar type declaration:

No new reserved words were added. int, float, string, and bool are recognized as type declarations, and are also prohibited for naming as class/interface/trait. The new user scalar type declaration is implemented through the internal fast Parameter parsing API.

Strict_types/declare () directive

By default, all PHP files are in weak type check mode. The new declare instruction, by specifying the value of the Strict_types (1 or 0), 1 for the strict type check mode, for function calls and return statements, and 0 for weak type check mode.

DECLARE (Strict_types=1) must be the first statement of a file. If this statement appears elsewhere in the file, a compilation error will occur, and the block pattern is explicitly forbidden.

Similar to the encoding directive, but unlike the Ticks directive, the Strict_types directive only affects files that are specified for use, and does not affect other files that it contains (through include, etc.). This instruction is compiled at run time and cannot be modified. It works by setting a flag bit in opcode that allows the function call and return type check to conform to the type constraint.


Parameter type declaration

This directive affects all function calls, such as (strict check mode):

<?php  Declare (strict_types=1);  Foo ();  Strictly type-checked Functioncall function Foobar () {      foo ();//Strictly type-checked function call}  class Baz {         function Foobar () {                 foo ();//Strictly type-checked function call       }}

Contrast (weak check mode)

<?phpfoo (); Weakly type-checked function CallFunction foobar () {   foo ();//weakly type-checked function Call}class Baz {functio n Foobar () {foo ();//weakly type-checked function call}}?>

return type declaration:

Directives affect the return type of all functions under the same file. For example (strict check mode):

<?phpdeclare (Strict_types=1); function foobar (): int {return 1.0;//Strictly type-checked return} class Baz {function f Oobar (): int {return 1.0;//Strictly type-checked return}}?>

<?phpfunction foobar (): int {return 1.0;//weakly type-checked return} class Baz {function Foobar (): int {return 1.0; Weakly type-checked return}}?>


Weak type check behavior:

A function call for a weak type check is consistent with the PHP version prior to PHP7 (including extensions and PHP built-in functions). Generally, weak type validation rules are the same for new scalar type declarations, but the only exception is the handling of NULL. To be consistent with our existing class, invocation, and type declarations of arrays, NULL is not the default unless it is a parameter and is explicitly assigned null.

To give a short summary to readers who are unfamiliar with PHP's existing weak scalar parameter type rules. The table shows scalar type declarations that can be accepted and converted by different types, and NULL, arrays, and resource cannot accept scalar type declarations, so they are not inside the table.

* Only non-nanfloat types within the range of php_int_min and Php_int_max are acceptable. (PHP7 new, can view zpp Failure on Overflow RFC)

? The non-numeric string is not accepted, and the numeric string follows the string, which can also be accepted, but produces a notice.

? Only if it has the ToString method.

Strict type check behavior:

A strict type check call extension or PHP built-in function will change the behavior of zend_parse_parameters. It is especially important to note that when it fails, it produces e_recoverable_error instead of e_warning. It follows strict type-checking rules, not traditional weak-type validation rules. A strict type check rule is very straightforward: it is accepted only if the type and the specified type declaration match, otherwise it is rejected.

One exception is that a broad type conversion allows an int to become float, that is, if the parameter is declared as a float type, but it can still accept the int parameter.

<?phpdeclare (Strict_types=1), function add (float $a, float $b): float {return $a + $b;} Add (1, 2); Float (3)?>

In this scenario, we pass an int argument to the function that defines the accept float, and this parameter is converted to float. In addition, the conversion is not allowed.

Third, examples:

Let's create a function that adds up to 2 numbers.

add.php<?phpfunction Add (int $a, int $b): int {return $a + $b;}? >

If in separate files, we can call the Add function by way of a weak type

<?phprequire "add.php"; var_dump (add); Int (3)//floats is truncated by defaultvar_dump (Add (1.5,2.5)); Int (3)//strings convert if there ' s a number partvar_dump (Add ("1", "2")); Int (3)?>

By default, weak type declarations allow conversions, and the values passed in are converted.

<?phprequire "add.php"; Var_dump (Add ("1foo", "2")); Int (3)//NOTICE:A non well formed numeric value encountered


However, after you turn on strict type checking with the optional instruction declare, the same call will fail in this scenario.

<?phpdeclare (Strict_types=1); require "add.php"; var_dump (add); Int (3) var_dump (Add (1.5,2.5)); Int (3)//catchable fatal Error:argument 1 passed to add () must is of the type integer, float given

Directives affect all function calls under the same file, regardless of whether the called function is defined within this file, the strict type check mode is used.

<?php declare (Strict_types=1); $foo = substr (52,1);//catchable fatal Error:substr () expects parameter 1 to be string, integer given

Scalar type declarations can also be used for strict type checking of return values:

<?phpfunction foobar (): int {return 1.0;} Var_dump (Foobar ());//int (1)

In weakly typed mode, float is converted to integer.

<?phpdeclare (Strict_types=1); function foobar (): int {return 1.0;} Var_dump (Foobar ());//catchable fatal Error:return value of Foobar () must be of the type integer,float returned

Iv. background and theoretical basis

History

PHP already has support for class and interface parameter type declarations starting from PHP5.0, PHP5.1 supports array and PHP5.4 support callable. These types of declarations allow PHP to pass in the correct parameters at execution time, allowing the function signature to have more information.

I had previously wanted to add scalar type declarations, such as the scalar type Hints with casts RFC, for various reasons failed:

(1) Type conversion and validation mechanism, for extension and PHP built-in functions do not match.

(2) It follows a weak type method.

(3) It's "strict" weak type modification attempt, neither satisfies the strict type fan expectation, nor satisfies the weak type fan.

This RFC attempts to resolve all issues.

Weakly typed and strongly typed

In the practical application of modern programming languages, there are three main ways to check the types of parameters and return values:

(1) Strict type checking (that is, no type conversions occur). Examples include the use of hack for F #, GO, Haskell, Rust, and Facebook.

(2) extensive raw type checking ("Safe" type conversions will occur). Examples include Java, d, and Pascal. They allow extensive primitive type conversions (implicit conversions), meaning that an 8-bit integer can be invisible to a 16-bit integer based on function parameters, and int can also be converted to float's floating-point number. Other types of implicit conversions are not allowed.

(3) weak type checking (which allows all types of conversions, which can cause warnings), is restricted to use in C, C #, C + +, and Visual Basic. They try to complete a conversion as "no failure" as possible.

PHP's scalar internal processing mechanism in Zend_parse_parameters uses a weakly typed pattern. PHP's object handling mechanism employs a wide range of types, and does not pursue exact matching and conversion.

Each method has its advantages and disadvantages.

In this proposal, the weak type check mechanism is used by default, and a switch is appended to allow conversion to a wide type validation mechanism (that is, strict type checking mechanism).

Why are both supported?

So far, most proponents of scalar type declarations have demanded that both strict type checksums and weak type checksums be supported, not just one. This RFC makes the weak type check the default behavior, while adding an optional directive to use strict type checking (in the same file). There are a number of reasons behind this choice.

A large part of the PHP community looks like a full-static type. However, adding a scalar type declaration with strict type checking will cause some problems:

(1) Obvious inconsistencies: extensions and PHP built-in functions use weak type validation on scalar type parameters, but the user's PHP function will use strict type validation.

(2) A significant proportion of people prefer weak-type verification, and disagree with the proposal that they might prevent it from being implemented.

(3) The existing code uses the weak type of PHP, which is affected. If a function is required to add a scalar type declaration to a parameter, this will greatly increase the complexity for the existing code base, especially for the library file.

There are still some people who prefer weak type checking, but adding a strict type check declaration and adding a weak type check declaration can cause some problems:

(1) Most people who prefer strict type checking will not like the proposal and then prevent it from being implemented.

(2) Limit the chance of static parsing. (may be that the opportunity to optimize)

(3) It hides some of the bugs in data loss in type auto-conversions.

The third scenario is proposed, which is to add a syntax that distinguishes between weakly typed and strict type declarations. It also poses some problems:

(1) People who do not like weak types and strict type checking are forced to deal with libraries that are defined as strict or weak type checks respectively.

(2) Like adding a strict declaration, this will also be the extension of the original weak type implementation and PHP built-in functions can not be consistent.

To address the problems posed by these three scenarios, this RFC proposes a fourth scenario: each file has its own strict or weak type checksum. It brings the following benefits:

(1) People can choose the type of calibration that suits them, that is, this scheme wants to satisfy both strict and weak type check two camps.

(2) The API is not forced to adapt to a type declaration pattern.

(3) because the file defaults to the weak type validation scheme, the existing code base can add scalar type declarations without breaking the code structure. You can also have the code base incrementally add a type declaration, or just some modules to add.

(4) A scalar type declaration can be defined only if a single syntax is required.

(5) People who prefer strict type checking, usually not only use this feature in user-defined functions, but also in extensions and PHP built-in functions. In other words, PHP users get a uniform mechanism without the contradiction of strict scalar declarations.

(6) In the strict type check mode, extension and PHP built-in function generated by the type validation failure level, and user-defined function will be consistent, are e_recoverable_error.

(7) It allows strict-type and weakly-typed code to be seamlessly integrated in a single code base.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.