鍵入提示標量型別陣列和可呼叫項

在 PHP 5.1 中新增了關鍵字 array 的型別提示陣列引數(以及 PHP 7.1 之後的返回值)的支援。任何維度和型別的任何陣列以及空陣列都是有效值。

在 PHP 5.4 中新增了對型別提示可呼叫的支援。is_callable() 對引數和返回值有效的任何值都暗示了 callable,即 Closure 物件,函式名字串和 array(class_name|object, method_name)

如果函式名中出現拼寫錯誤,使其不是 is_callable(),則會顯示一條不太明顯的錯誤訊息:

致命錯誤:未捕獲的 TypeError:傳遞給 foo() 的引數 1 必須是可呼叫的型別,給定的字串/陣列

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

foo("no_such_function"); // callable expected, string given

非靜態方法也可以作為靜態格式的 callable 傳遞,導致 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:傳遞給 r() 的引數 1 必須是可呼叫的,給定陣列

在 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) 的呼叫會產生完全相同的輸出,因為浮動 1.5 由 PHP 轉換為 int

要停止此行為,必須將 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:傳遞給 add() 的引數 1 必須是 integer 型別,float 給定

例外:特殊型別

某些 PHP 函式可能返回 resource 型別的值。由於這不是標量型別,而是特殊型別,因此無法鍵入提示。

舉個例子,curl_init() 將返回 resource,以及 fopen()。當然,這兩種資源彼此不相容。因此,當明確鍵入提示 resource 時,PHP 7 將始終丟擲以下 TypeError:

TypeError:傳遞給 sample() 的引數 1 必須是資源的例項,給定資源