Type Hinting: Default Parameters

2019-01-11 12:10发布

问题:

PHP 5 Type Hinting

PHP 5 introduces Type Hinting. Functions are now able to force parameters to be objects (by specifying the name of the class in the function prototype) or arrays (since PHP 5.1). However, if NULL is used as the default parameter value, it will be allowed as an argument for any later call.

The following excerpt from the above:

if NULL is used as the default parameter value, it will be allowed as an argument for any later call.

Does the above mean:

if default parameters are to used use with type hinting, it can have only have NULL as the default value.

i.e. the code in code1 is wrong and results in:

Fatal error: Default value for parameters with a class type hint can only be NULL

code1:

 function setName ( string $name = "happ") {
  ...
  }

Where as code in code2 is right:

code2:

 function setName ( string $name = NULL) {
  ...
  }

Why is this constraint assigned in php?

回答1:

You can't typehint strings, you can only typehint objects and arrays, so this is incorrect:

function setName ( string $name = "happ") {

(The reason you don't get a compile-time error here is because PHP is interpreting "string" as the name of a class.)

The wording in the docs means that if you do this:

function foo(Foo $arg) {

Then the argument passed to foo() must be an instance of object Foo. But if you do this:

function foo(Foo $arg = null) {

Then the argument passed to foo() can either be an instance of object Foo, or null. Note also that if you do this:

function foo(array $foo = array(1, 2, 3))

Then you can't call foo(null). If you want this functionality, you can do something like this:

function foo(array $foo = null) {
    if ($foo === null) {
        $foo = array(1, 2, 3);
    }

[Edit 1] As of PHP 5.4, you can typehint callable:

function foo(callable $callback) {
    call_user_func($callback);
}

[Edit 2] As of PHP 7.0, you can typehint bool, float, int, and string. This makes the code in the question valid syntax. As of PHP 7.1, you can typehint iterable.



回答2:

Type declarations (also known as type hints in PHP 5) of a string type are supported in PHP 7.

The valid types are:

  • Class/interface name (>=PHP 5.0.0);
  • self (>=PHP 5.0.0);
  • array (>=PHP 5.1.0);
  • callable (>=PHP 5.4.0);
  • bool, float, int, string (>=PHP 7.0.0);
  • iterable - either an array or an instanceof Traversable (>=PHP 7.1.0).


回答3:

This is a matter of compilation time versus run time values. At compilation only literal values (strings, numbers, booleans and NULL) are allowed. The PHP processor can't know about all the possible classes at this time and so you can't create an instance of an object in the function arguments.

What I'm expecting from the excerpt is that, while normally passing NULL into a type hinted function will throw an Exception/Error. If you set a default as NULL then it won't throw this exception if NULL is passed. I haven't tested it, just what I would expect.