Author: Joseluis Laso
Updated on: 2015-03-24
Posted on: 2015-03-23
Categories: PHP Tutorials
Read this article to understand what scalar type hinting is and how you can benefit from it when you will run your code with PHP 7.
Contents
What is Scalar Type Hinting?
The Scalar Type Checking Proposals
Explicit Declaration of Scalar Types: int, float, string and bool
Examples of Declarations and Usage
Behavior of Weak Type Checking and Type Conversion
Behavior of Strict Type Checking
A bit of History about Type Hinting
Personal Opinion
Coherence to Maintain Old Code
Conclusion
What is Scalar Type Hinting?
Scalar type hinting consists of declaring the types of function parameters and return values that can be of the types int, float, string and bool.
This allows the PHP runtime engine to check if the types of values passed to parameter functions and return values are of the expected types in order to detect eventual programming mistakes.
Type hinting for objects, arrays and callables was already allowed in past PHP versions. This proposal extends the type hinting support for types of values known as scalar because they contain only one primitive value, as opposed to non-scalar types which are those that may contain complex values like objects and arrays.
The Scalar Type Checking Proposals
This proposal was approved on March 16 with 108 votes and 48 votes against. It was one of the highest vote counts, if not the highest vote count so far. This reflects the interest of this matter for the PHP community that wants PHP to evolve and become a better language.
This proposal by Anthony Ferrara derived from another proposal by Andrea Faulds submitted on December 2014.
Other proposals for the similar purposes were already submitted and debated intensively in the past. Here is a list of some of those other proposals:
- 2009-06-03: Strict and weak parameter type checking
- 2012-03-03: Scalar Type Casting Magic Methods
- 2012-07-03: Scalar Type Hinting With Casts
- 2015-02-27: Coercive Types for Function Arguments
- 2015-03-11: Basic Scalar Types
Explicit Declaration of Scalar Types: int, float, string and bool
This new possibility will allow PHP 7 function declarations to look like this:
function increment(int $a): int {...}
This new form of function declaration can coexist with the previous form that did not allow scalar type hinting. Lets see how.
You can add the statement declare(strict_types=1); in the source file on which you intend to allow scalar type hinting. Note that this declaration has to be on the first line of the PHP file and can not be declared elsewhere in the same file.
Another aspect to note is whether or not the function being called was declared in a file that uses strict or weak type checking is irrelevant. The type checking mode depends on the file where the function is called. That makes sense, right?
In other words, I expect that all the files in a given project will use either weak or strict mode. The only problem will be with the third-party libraries, as I comment ahead.
Examples of Declarations and Usage
Once we have declared at the beginning of a PHP file to use strict_types=1, we can explicitly declare the types of scalar arguments and return of functions inside this file, so they can be strictly checked.
This reminds me the "use strict"; declaration at the beginning of JavaScript files. As a matter of fact some people suggested a similar option for strict declaration.
A simple example
<?php
declare(strict_types=1); function increment(int $a): int { return $a + 1.0; // strictly type checked return } class Foo { function increment(int $a): int { return $a + 1.0; // strictly type checked return } }
At runtime, when the PHP engine tries to return a value, it will check if it matches the declared type and will throw a fatal error if does not match.
Fatal error: Argument 1 passed to increment() must be of the type integer, string given
With this new feature we can declare scalar types: int, float, string and bool. Until PHP 5.x we could only "pseudo-declare" these types using PHPdoc or comments, but those are declarations that do not have any implication at runtime.
With this new form declaration, we can write more robust applications by detecting early programming mistakes caused by passing values of the wrong types to and from functions.
Notice: The aliases of integer for int and boolean for bool are not admitted.
Automatic promotion of types may also happen. For instance, int types can be promoted to float type parameters automatically:
function foo(float $a): float {...}
foot(10); // works fine
Declaring the Return Type
Using a Delphi-like flavor syntax, we can declare the return types adding a colon followed by the expected type between the last parenthesis and the first bracket in the function declaration.
For functions that do not return any value, nothing should be added in the return type declaration section.
function mustReturnInt(): int { ... }
function mustReturnString(): string { ... }
function mustReturnBool(): bool { ... }
function mustReturnFloat(): float { ... }
function doesNotReturnAnything() { ... }
A Little Bit more Complex Example
<?php declare(strict_types=1); class StrictTypesTestingClass { public function returnSameInt(int $value): int { return $value; } public function returnSameFloat(float $value): float { return $value; } public function returnSameString(string $value): string { return $value; } public function returnSameBool(bool $value): bool { return $value; } } $check = new StrictTypesTestingClass(); // calls that work print $check->returnSameInt(10); print $check->returnSameFloat(10.0); print $check->returnSameString("test"); print $check->returnSameBool(true) ? 'true' : 'false'; // calls that throw exceptions print $check->returnSameInt("10"); print $check->returnSameFloat("10.0"); print $check->returnSameString(10); print $check->returnSameBool("true");
Behavior of Weak Type Checking and Type Conversion
The weak type checking mode can be used with the statement declare(strict_types=0); or the absence of the strict types declaration. There are a few of points to take into account:
Weak type checked calls to an extension or built-in PHP function have the same behaviour as in previous PHP versions
The weak type checking rules for new scalar type declarations are mostly the same as those of extension or built-in PHP functions.
NULL is a special case in order to be consistent with the current type declarations for classes, callables and arrays. NULL is not accepted by default, unless it is a parameter and is explictly given a default value of NULL, for instance: function sample(int $a = NULL);
The following table summarizes the implicit scalar type conversion in weak mode. In any case NULL, arrays and resources are never accepted for scalar type declarations.
Type declaration | int | float | string | bool | object |
---|---|---|---|---|---|
int | yes | yes1 | yes2 | yes | no |
float | yes | yes | yes2 | yes | no |
string | yes | yes | yes | yes | yes3 |
bool | yes | yes | yes | yes | no |
1) Only non-NaN floats between PHP_INT_MIN and PHP_INT_MAX are accepted. (New in PHP 7, see the ZPP Failure on Overflow RFC)
2) Non-numeric strings not accepted. Numeric strings with trailing characters are accepted, but produce a notice.
3) Only if it has a __toString method.
Behavior of Strict Type Checking
The strict type check mode corresponds with the use of
declare(strict_types=1)
at the beginning of the PHP file.
A strictly type-checked call to an extension or built-in PHP function will produce catchable error rather than E_WARNING on failure, and it follows strict type checking rules for scalar typed parameters, rather than the traditional weak type checking rules.
The strict type checking rules are quite straightforward: when the type of the value matches the one specified in the type declaration, it is accepted, otherwise it is not.
These strict type checking rules are used for "userland" scalar type declarations, and for extension functions and built-in PHP functions.
Note: The only exception is that scalar type conversion is allowed for int to float. This means that parameters that declare float can also accept int.
A bit of History about Type Hinting
Past PHP versions have already supported type hinting on non-scalar types types:
- 5.0 for objects
- 5.1 for array
- 5.4 for callable
Extending this support to scalar types (int, float, bool and string) has been debated many times over the last years, each time with a bit more support, and finally, last March 16 type hinting for scalar types was approved.
Anthony Ferrara says in ircmaxell's blog:
-
A portion of the community wants strict only types. So that if you declare function foo(int $abc) and pass in a non-integer, it will raise an error.
There are a ton of advantages to this approach. You get type safety. Which means that you can finally statically analyze code! You can detect bugs where you accidentally take a string from one function and pass it as an integer to another.
That may not seem like a big deal to you at first. The reason is that while it may be appropriate in some cases, in many it isn't. So computers can't reason about that code ahead of time (statically) and therefore can't be sure that the operation will work.
As I mentioned at the beginning of this post, this subject has been debated for a long time in several occasions. I am really not sure why this time it has finally been approved because many people voted with explaining their reasons. I suspect that the reasons can be:
- The RFC was presented in a very simple way.
- The options were reduced to the minimum.
- The opportunity of RFC in time was perfect because there were a lot of similar RFC proposals recently, sooner or later one would be approved a scalar type hinting RFC.
- Respect for previous behavior in order to maintain the backwards compatibility.
- Having it disabled by default will not hurt the performance of code that does not use type checking.
Personal Opinion
Personally I cannot wait for this new improvement. I want to forget the past years that I had to use my intuition to figure what types of arguments a function expects or what can I expect as a return value.
Every day I write hundred of lines of PHP code and try to apply the best practices that I know: PSR, naming conventions, programming principles. Years ago I embraced Symfony as my professional development framework. Quickly I felt fine using it because it allows me to control things that legacy code does not.
For me, a developer that uses PHP on a daily basis and sees Java as a reference for OOP languages, this is great progress for PHP.
Coherence to Maintain Old Code
Of course, weak mode can be used by "legacy" or skeptical developers. The default behavior of PHP when this feature be implemented will be the weak mode, ensuring that the old code works fine.
Authors of code and libraries will decide if they will adapt their code or not, and the users of these libraries can decide if they use or not the new mode.
Remember that the new behavior of strict mode is applied in the PHP where the function is invoked.
Conclusion
Good job for the developers that voted in this proposal, specially to Andrea Faulds and Anthony Ferrara that created a proposal that was finally accepted by the majority of the voters.
What do you think of this proposal? Do you agree with it or not? Do you think it will contribute to develop better PHP code? Post a comment here to let us know your opinion.
You need to be a registered user or login to post a comment
1,454,430 PHP developers registered to the PHP Classes site.
Be One of Us!
Login Immediately with your account on:
Comments:
7. type hint - caterina gordo (2017-06-30 07:07)
type hint bool and int... - 0 replies
Read the whole comment and replies
6. About time! - Matthew Hellinger (2015-05-06 20:30)
This will be good for PHP... - 0 replies
Read the whole comment and replies
3. wrong message and login strict type checking sampe - ing. conti (2015-03-24 13:50)
error does not fit well with promotion... - 4 replies
Read the whole comment and replies
5. A yay and a no - Rafael den Heijer (2015-03-24 13:48)
Declare? Why? Strong typing! Yes!... - 1 reply
Read the whole comment and replies
1. RE: personal opinion - Joeri Sebrechts (2015-03-24 13:01)
Type hinting is good, but let's not chase after java... - 4 replies
Read the whole comment and replies
4. Re: PHP 7 Scalar Typehinting Finally Approved - Victor Passapera (2015-03-23 19:45)
Great news!... - 0 replies
Read the whole comment and replies
2. Great job! - Sandro Alves Peres (2015-03-23 14:13)
Opinion... - 1 reply
Read the whole comment and replies