PHP 类型提示标量类型,数组和可调用对象

示例

在PHP 5.1中,使用关键字添加了对类型提示数组参数的支持(以及PHP 7.1之后的返回值)array。任何尺寸和类型的数组以及空数组都是有效值。

在PHP 5.4中添加了对类型提示可调用对象的支持。is_callable()对于参数有效的任何值并提示所返回的值callable,即Closure对象,函数名称字符串和array(class_name|object, method_name)。

如果在函数名称中出现错字而不是is_callable(),则会显示不太明显的错误消息:

致命错误:未捕获的TypeError:传递给的参数1foo()必须是可调用的类型,给定的字符串/数组

function foo(callable $c) {}
foo("count"); // 有效
foo("Phar::running"); // 有效
foo(["Phar", "running"); // 有效
foo([new ReflectionClass("stdClass"), "getName"]); // 有效
foo(function() {}); // 有效

foo("no_such_function"); // 可预期的,给定的字符串

非静态方法也可以以静态格式作为可调用对象传递,从而分别导致PHP 7和5中的弃用警告和E_STRICT级错误。

考虑到方法的可见性。如果带有callable参数的方法上下文无法访问所提供的可调用对象,则它将结束,就好像该方法不存在一样。

class Foo{
  private static function f(){
    echo "Good" . PHP_EOL;
  }

  public static function r(callable $c){
    $c();
  }
}

function r(callable $c){}

Foo::r(["Foo", "f"]);
r(["Foo", "f"]);

输出:

致命错误:未捕获的TypeError:传递给参数1r()必须是可调用的,给定数组

在PHP 7中添加了对类型提示标量类型的支持。这意味着我们获得了对booleans,integers,floats和strings的类型提示支持。

<?php

function add(int $a, int $b) {
    return $a + $b;
}

var_dump(add(1, 2)); // Outputs "int(3)"

默认情况下,PHP将尝试强制转换提供的任何参数以匹配其类型提示。add(1.5, 2)由于将float1.5转换int为PHP ,因此将调用更改为会得到完全相同的输出。

要停止这种行为,必须declare(strict_types=1);在每个需要它的PHP源文件的顶部添加一个。

<?php

declare(strict_types=1);

function add(int $a, int $b) {
    return $a + $b;
}

var_dump(add(1.5, 2));

上面的脚本现在产生一个致命错误:

致命错误:未捕获的TypeError:传递给的参数1add()必须为整数类型,给定float

例外:特殊类型

一些PHP函数可能返回type值resource。由于这不是标量类型,而是特殊类型,因此无法键入提示。

例如,curl_init()将返回resource和fopen()。当然,这两种资源彼此不兼容。因此,PHP 7在显式进行类型提示时将始终抛出以下TypeError resource:

TypeError:传递给参数1的参数sample()必须是资源的实例,资源已给定