Just discovered that type-hinting is allowed in PHP, but not for ints, strings, bools, or floats.
Why does PHP not allow type hinting for types like integer, strings, ... ?
Just discovered that type-hinting is allowed in PHP, but not for ints, strings, bools, or floats.
Why does PHP not allow type hinting for types like integer, strings, ... ?
As of PHP 7.0 there is support for
bool
,int
,float
andstring
. Support was added in the scalar types RFC. There are two modes: weak and strict. I recommend reading the RFC to fully understand the differences, but essentially type conversions only happen in weak mode.Given this code:
Under weak mode (which is the default mode) this will convert
"1"
to1
.To enable strict types add
declare(strict_types=1);
to the top of the file. Under strict mode an error will be emitted:It is not proper to call it "type hinting". "Hinting" implies it's some optional typing, a mere hint rather than requirement, however typed function parameters are not optional at all - if you give it wrong type, you get the fatal error. Calling it "type hinting" was a mistake.
Now to the reasons why there's no primitive typing for function parameters in PHP. PHP does not have a barrier between primitive types - i.e., string, integer, float, bool - are more or less interchangeable, you can have
$a = "1";
and thenecho $a+3;
and get4
. All internal functions also work this way - if the function expects a string and you pass an integer, it's converted to string, if the function expects a float and gets an integer, it is converted to float, etc. This is unlike object types - there's no conversion between, say,SimpleXMLElement
andDirectoryIterator
- neither there could be, it wouldn't make any sense.Thus, if you introduce function that accepts integer
1
and not string1
, you create incompatibility between internal functions and user functions and create problems for any code that assumes those are pretty much the same. This would be a big change in how PHP programs behave, and this change will need to be propagated through all the code using such functions - since otherwise you risk errors when transitioning between "strict" and "non-strict" code. This would imply a necessity of types variables, typed properties, typed return values, etc. - big change. And since PHP is not a compiled language, you do not get benefits of static type control with the downsides of it - you only get inconveniences but not the added safety. This is the reason why parameter typing is not accepted in PHP.There is another option - coercive typing, i.e. behavior analogous to what internal functions do - convert between types. Unfortunately, this one does not satisfy the proponents of strict typing, and thus no consensus is found so far, and thus none is there.
On the other hand, object types were never controversial - it is clear that there's no conversion between them, no code assumes they are interchangeable and checks can only be strict for them, and it is the case with both internal and external functions. Thus, introducing strict object types was not a problem.
PHP's loosely typed, where your "primitive" types are automatically type-juggled based on the context in which they're used. Type-hinting wouldn't really change that, since a string could be used as an int, or vice versa. Type-hinting would only really be helpful for complex types like arrays and objects, which can't be cleanly juggled as ints, strings, or other primitives.
To put it another way, since PHP has no concept of specific types, you couldn't require an int somewhere because it doesn't know what an int really is. On the other hand, an object is of a certain type, since a MyClass is not interchangeable with a MyOtherClass.
Just for reference, here's what happens when you try to convert between such types (not an exhaustive list):
Converting to Object (ref)
"If an object is converted to an object, it is not modified. If a value of any other type is converted to an object, a new instance of the stdClass built-in class is created. If the value was NULL, the new instance will be empty. Arrays convert to an object with properties named by keys, and corresponding values. For any other value, a member variable named scalar will contain the value."
Object to int/float (ref)
undefined behavior
Object to boolean (ref)
in PHP5, always TRUE
Object to string (ref)
The object's
__toString()
magic method will be called, if applicable.Object to array (ref)
"If an object is converted to an array, the result is an array whose elements are the object's properties. The keys are the member variable names, with a few notable exceptions: integer properties are unaccessible; private variables have the class name prepended to the variable name; protected variables have a '*' prepended to the variable name. These prepended values have null bytes on either side. This can result in some unexpected behaviour."
Array to int/float (ref)
undefined behavior
Array to boolean (ref)
If the array is empty (i.e., no elements), it evaluates to FALSE -- otherwise, TRUE.
Array to string (ref)
the string "Array"; use
print_r()
orvar_dump()
to print the contents of an arrayArray to object (ref)
"Arrays convert to an object with properties named by keys, and corresponding values."