男女疯狂一边摸一边做羞羞视频|啊好深好硬快点用力别停动态图|亚洲一区无码中文字幕|特级无码毛片免费视频播放▽|久久狠狠躁免费观看|国内精品久久久久久网站

類(lèi)型聲明

類(lèi)型聲明可以用于函數的參數、返回值,PHP 7.4.0 起還可以用于類(lèi)的屬性,來(lái)顯性的指定需要的類(lèi)型,如果預期類(lèi)型在調用時(shí)不匹配,則會(huì )拋出一個(gè) TypeError 異常。

注意:

當子類(lèi)覆蓋父方法時(shí),子類(lèi)的方法必須匹配父類(lèi)的類(lèi)型聲明。如果父類(lèi)沒(méi)有定義返回類(lèi)型,那么子方法可以指定自己的返回類(lèi)型。

單一類(lèi)型

類(lèi)型 說(shuō)明 版本
類(lèi)/接口 名稱(chēng) 值必須為指定類(lèi)和接口的實(shí)例化對象 instanceof  
self 值必須是用于類(lèi)型聲明相同類(lèi)的 instanceof 。 僅可在類(lèi)中使用。  
parent 值必須是用于類(lèi)型聲明父級類(lèi)的 instanceof , 僅可在類(lèi)中使用。  
array 值必須為 array。  
callable 值必定是一個(gè)有效的 callable。 不能用于類(lèi)屬性的類(lèi)型聲明。  
bool 值必須為一個(gè)布爾值。  
float 值必須為一個(gè)浮點(diǎn)數字。  
int 值必須為一個(gè)整型數字。  
string 值必須為一個(gè) string。  
iterable 值必須為 arrayinstanceof Traversable。 PHP 7.1.0
object 值必須為object。 PHP 7.2.0
mixed 值可以為任何類(lèi)型。 PHP 8.0.0
警告

不支持上述標量類(lèi)型的別名。相反,它們被視為類(lèi)或接口名。例如,使用 boolean 作為類(lèi)型聲明,將要求值是一個(gè) instanceof 類(lèi)或接口 boolean,而不能是類(lèi)型 bool。

<?php
    
function test(boolean $param) {}
    
test(true);
?>

以上例程在 PHP 8 中的輸出:

Warning: "boolean" will be interpreted as a class name. Did you mean "bool"? Write "\boolean" to suppress this warning in /in/9YrUX on line 2

Fatal error: Uncaught TypeError: test(): Argument #1 ($param) must be of type boolean, bool given, called in - on line 3 and defined in -:2
Stack trace:
#0 -(3): test(true)
#1 {main}
  thrown in - on line 2

mixed

mixed 等同于 聯(lián)合類(lèi)型 object|resource|array|string|int|float|bool|null。PHP 8.0.0 起可用。

范例

示例 #1 在類(lèi)中使用類(lèi)型聲明

<?php
class {}
class 
extends {}

// 它沒(méi)有 extend C。
class {}

function 
f(C $c) {
    echo 
get_class($c)."\n";
}

f(new C);
f(new D);
f(new E);
?>

以上例程在 PHP 8 中的輸出:

C
D

Fatal error: Uncaught TypeError: f(): Argument #1 ($c) must be of type C, E given, called in /in/gLonb on line 14 and defined in /in/gLonb:8
Stack trace:
#0 -(14): f(Object(E))
#1 {main}
  thrown in - on line 8

示例 #2 在接口中使用類(lèi)型聲明

<?php
interface { public function f(); }
class 
implements { public function f() {} }

// 它沒(méi)有 implement I。
class {}

function 
f(I $i) {
    echo 
get_class($i)."\n";
}

f(new C);
f(new E);
?>

以上例程在 PHP 8 中的輸出:

C

Fatal error: Uncaught TypeError: f(): Argument #1 ($i) must be of type I, E given, called in - on line 13 and defined in -:8
Stack trace:
#0 -(13): f(Object(E))
#1 {main}
  thrown in - on line 8

示例 #3 返回類(lèi)型聲明

<?php
function sum($a$b): float {
    return 
$a $b;
}

// 注意必須返回一個(gè) float。
var_dump(sum(12));
?>

以上例程會(huì )輸出:

float(3)

示例 #4 返回一個(gè)對象

<?php
class {}

function 
getC(): {
    return new 
C;
}

var_dump(getC());
?>

以上例程會(huì )輸出:

object(C)#1 (0) {
}

允許為空的(Nullable)類(lèi)型

自 PHP 7.1.0 起,類(lèi)型聲明允許前置一個(gè)問(wèn)號 (?) 用來(lái)聲明這個(gè)值允許為指定類(lèi)型,或者為 null。

示例 #5 定義可空(Nullable)的參數類(lèi)型

<?php
class {}

function 
f(?C $c) {
    
var_dump($c);
}

f(new C);
f(null);
?>

以上例程會(huì )輸出:

object(C)#1 (0) {
}
NULL

示例 #6 定義可空(Nullable)的返回類(lèi)型

<?php
function get_item(): ?string {
    if (isset(
$_GET['item'])) {
        return 
$_GET['item'];
    } else {
        return 
null;
    }
}
?>

注意:

可以通過(guò)設置參數的默認值為 null 來(lái)實(shí)現允許為空的參數。不建議這樣做,因為影響到類(lèi)的繼承調用。

示例 #7 舊版本中實(shí)現允許為空參數的示例

<?php
class {}

function 
f(C $c null) {
    
var_dump($c);
}

f(new C);
f(null);
?>

以上例程會(huì )輸出:

object(C)#1 (0) {
}
NULL

復合類(lèi)型

還可以組合簡(jiǎn)單類(lèi)型為復合類(lèi)型。 PHP 支持以下方式復合類(lèi)型:

  • 簡(jiǎn)單類(lèi)型聯(lián)合。PHP 8.0.0 起可用。
  • class-type(接口、類(lèi)名)類(lèi)型交集。PHP 8.1.0 起可用。
警告

無(wú)法復合交集類(lèi)型與聯(lián)合類(lèi)型。

聯(lián)合類(lèi)型

聯(lián)合類(lèi)型接受多個(gè)不同的簡(jiǎn)單類(lèi)型做為參數。聲明聯(lián)合類(lèi)型的語(yǔ)法為 T1|T2|...。聯(lián)合類(lèi)型自 PHP 8.0.0 起可用。

允許為空的聯(lián)合類(lèi)型

null 類(lèi)型允許在聯(lián)合類(lèi)型中使用,例如 T1|T2|null 代表接受一個(gè)空值為參數。已經(jīng)存在的 ?T 語(yǔ)法可以視為以下聯(lián)合類(lèi)型的一個(gè)簡(jiǎn)寫(xiě) T|null。

警告

null 不能作為一個(gè)獨立的類(lèi)型使用。

false 偽類(lèi)型

通過(guò)聯(lián)合類(lèi)型支持字面類(lèi)型(Literal Type)false, 出于歷史原因,很多內部函數在失敗時(shí)返回了 false 而不是 null。 這類(lèi)函數的典型例子是 strpos()。

警告

false 不能單獨作為類(lèi)型使用(包括可空 nullable 類(lèi)型)。 因此,不可以用 false、false|null、 ?false。

警告

true 字面類(lèi)型不存在。

交集類(lèi)型

只要能滿(mǎn)足 class-type 的值,都可以在交集類(lèi)型聲明中使用,并且可使用多個(gè)值。 交集類(lèi)型用 T1&T2&... 這樣的語(yǔ)法指定。 交集類(lèi)型從 PHP 8.1.0 可以使用。

重復冗余的類(lèi)型

為了能在復合類(lèi)型聲明中暴露簡(jiǎn)單的 bug,不需要加載 class 就可以在編譯時(shí)讓重復冗余的類(lèi)型產(chǎn)生錯誤。 包含:

  • 解析出來(lái)的類(lèi)型只能出現一次。例如這樣的類(lèi)型 int|string|INT、 Countable&Traversable&COUNTABLE 會(huì )導致錯誤。
  • 使用 mixed 會(huì )導致錯誤。
  • 對于聯(lián)合類(lèi)型:
    • 使用了 bool 時(shí)就不能再附帶使用 false。
    • 使用了 object 時(shí)就不能再附帶使用 class 類(lèi)型。
    • 使用了 iterable 時(shí),array、 Traversable 都不能再附帶使用。
  • 對于交集類(lèi)型:
    • 使用 class-type 以外的類(lèi)型會(huì )導致錯誤。
    • 使用 self、parent、 static 都會(huì )導致錯誤。

注意: 不過(guò)它不能確保類(lèi)型最小化,因為要達到這樣的效果,還要加載使用類(lèi)型的 class。

例如,假設 AB 都是一個(gè)類(lèi)的別名, 而 A|B 仍然是有效的,哪怕它可以被簡(jiǎn)化為 AB。 同樣的,如果 B extends A {},那 A|B 仍然是有效的聯(lián)合類(lèi)型,盡管它可以被簡(jiǎn)化為 A。

<?php
function foo(): int|INT {} // 不允許
function foo(): bool|false {} // 不允許
function foo(): int&Traversable {} // 不允許
function foo(): self&Traversable {} // 不允許

use as B;
function 
foo(): A|{} // 不允許 ("use" 是名稱(chēng)解析的一部分)
function foo(): A&{} // 不允許 ("use" 是名稱(chēng)解析的一部分)

class_alias('X''Y');
function 
foo(): X|{} // 允許 (運行時(shí)才能知道重復性)
function foo(): X&{} // 允許 (運行時(shí)才能知道重復性)
?>

僅僅返回類(lèi)型

void

void 是一個(gè)返回類(lèi)型,用于標識函數沒(méi)有返回值。 它不能是聯(lián)合類(lèi)型的一部分。 PHP 7.1.0 起可用。

注意:

從 PHP 8.1.0 起棄用引用返回 void 的函數, 因為這樣的函數是矛盾的。 之前,它在調用時(shí)已經(jīng)發(fā)出如下 E_NOTICEOnly variable references should be returned by reference。

<?php
function &test(): void {}
?>

never

never 是一種表示沒(méi)有返回的返回類(lèi)型。這意味著(zhù)它可能是調用 exit(), 拋出異?;蛘呤且粋€(gè)無(wú)限循環(huán)。所以,它不能作為聯(lián)合類(lèi)型的一部分。PHP 8.1.0 起可用。

在類(lèi)型理論用于中,never 是底層類(lèi)型。 意味著(zhù)它是其它所有類(lèi)型的子類(lèi)型,并且可以在繼承期間替換任何其他返回類(lèi)型。

static

它的值必須是一個(gè) class 的 instanceof,該 class 是調用方法所在的同一個(gè)類(lèi)。 PHP 8.0.0 起有效。

嚴格類(lèi)型

默認如果可能,PHP 會(huì )強制轉化不合適的類(lèi)型為想要的標量類(lèi)型。 比如,參數想要 string,傳入的是 int, 則會(huì )獲取 string 類(lèi)型的變量。

可以按文件開(kāi)啟嚴格模式。 在嚴格模式下,只能接受完全匹配的類(lèi)型,否則會(huì )拋出 TypeError。 唯一的例外是 int 值也可以傳入聲明為 float 的類(lèi)型。

警告

通過(guò)內部函數調用函數時(shí),不會(huì )受 strict_types 聲明影響。

要開(kāi)啟嚴格模式,使用 declare 開(kāi)啟 strict_types

注意:

文件開(kāi)啟嚴格類(lèi)型后的內部調用函數將應用嚴格類(lèi)型, 而不是在聲明函數的文件內開(kāi)啟。 如果文件沒(méi)有聲明開(kāi)啟嚴格類(lèi)型,而被調用的函數所在文件有嚴格類(lèi)型聲明, 那將遵循調用者的設置(開(kāi)啟類(lèi)型強制轉化), 值也會(huì )強制轉化。

注意:

只有為標量類(lèi)型的聲明開(kāi)啟嚴格類(lèi)型。

示例 #8 參數值的嚴格類(lèi)型

<?php
declare(strict_types=1);

function 
sum(int $aint $b) {
    return 
$a $b;
}

var_dump(sum(12));
var_dump(sum(1.52.5));
?>

以上例程在 PHP 8 中的輸出:

int(3)

Fatal error: Uncaught TypeError: sum(): Argument #1 ($a) must be of type int, float given, called in - on line 9 and defined in -:4
Stack trace:
#0 -(9): sum(1.5, 2.5)
#1 {main}
  thrown in - on line 4

示例 #9 參數值的類(lèi)型強制轉化

<?php
function sum(int $aint $b) {
    return 
$a $b;
}

var_dump(sum(12));

// 以下會(huì )強制轉化為整型,注意以下內容輸出!
var_dump(sum(1.52.5));
?>

以上例程會(huì )輸出:

int(3)
int(3)

示例 #10 返回值的嚴格類(lèi)型

<?php
declare(strict_types=1);

function 
sum($a$b): int {
    return 
$a $b;
}

var_dump(sum(12));
var_dump(sum(12.5));
?>

以上例程會(huì )輸出:

int(3)

Fatal error: Uncaught TypeError: sum(): Return value must be of type int, float returned in -:5
Stack trace:
#0 -(9): sum(1, 2.5)
#1 {main}
  thrown in - on line 5

聯(lián)合類(lèi)型的內部隱式強制轉化

沒(méi)有開(kāi)啟 strict_types 時(shí),標量類(lèi)型可能會(huì )限制內部隱式類(lèi)型轉化。 如果值的類(lèi)型不是聯(lián)合類(lèi)型中的一部分,則目標類(lèi)型會(huì )按以下順序:

  1. int
  2. float
  3. string
  4. bool
如果類(lèi)型出現在組合中,值可以按 PHP 現有的類(lèi)型語(yǔ)義檢測進(jìn)行內部隱式強制轉化,則會(huì )選擇該類(lèi)型。 否則會(huì )嘗試下一個(gè)類(lèi)型。

警告

有一個(gè)例外:當值是字符串,而 int 與 float 同時(shí)在組合中,將按現有的“數字字符串”檢測語(yǔ)義,識別首選的類(lèi)型。 例如,"42" 會(huì )選擇 int 類(lèi)型, 而 "42.0" 會(huì )選擇 float 類(lèi)型。

注意:

沒(méi)有出現在上面列表中的類(lèi)型則不是有效的內部隱式轉化目標。 尤其是不會(huì )出現內部隱式轉化 nullfalse 類(lèi)型。

示例 #11 類(lèi)型強制轉換為聯(lián)合類(lèi)型的例子

<?php
// int|string
42    --> 42          // 類(lèi)型完全匹配
"42"  --> "42"        // 類(lèi)型完全匹配
new ObjectWithToString --> "__toString() 的結果"
                      
// object 不兼容 int,降級到 string
42.0  --> 42          // float 與 int 兼容
42.1  --> 42          // float 與 int 兼容
1e100 --> "1.0E+100"  // float 比 int 大太多了,降級到 string
INF   --> "INF"       // float 比 int 大太多了,降級到 string
true  --> 1           // bool 與 int 兼容
[]    --> TypeError   // array 不兼容 int 或 string

// int|float|bool
"45"    --> 45        // int 的數字字符串
"45.0"  --> 45.0      // float 的數字字符串

"45X"   --> true      // 不是數字字符串,降級到 bool
""      --> false     // 不是數字字符串,降級到 bool
"X"     --> true      // 不是數字字符串,降級到 bool
[]      --> TypeError // array 不兼容 int、float、bool
?>

其他

示例 #12 傳引用參數的類(lèi)型

僅僅會(huì )在函數入口檢查傳引用的參數類(lèi)型,而不是在函數返回時(shí)檢查。 所以函數返回時(shí),參數類(lèi)型可能會(huì )發(fā)生變化。

<?php
function array_baz(array &$param)
{
    
$param 1;
}
$var = [];
array_baz($var);
var_dump($var);
array_baz($var);
?>

以上例程在 PHP 8 中的輸出:

int(1)

Fatal error: Uncaught TypeError: array_baz(): Argument #1 ($param) must be of type array, int given, called in - on line 9 and defined in -:2
Stack trace:
#0 -(9): array_baz(1)
#1 {main}
  thrown in - on line 2

示例 #13 捕獲 TypeError

<?php
declare(strict_types=1);

function 
sum(int $aint $b) {
    return 
$a $b;
}

try {
    
var_dump(sum(12));
    
var_dump(sum(1.52.5));
} catch (
TypeError $e) {
    echo 
'Error: '$e->getMessage();
}
?>

以上例程在 PHP 8 中的輸出:

int(3)
Error: sum(): Argument #1 ($a) must be of type int, float given, called in - on line 10
男女疯狂一边摸一边做羞羞视频|啊好深好硬快点用力别停动态图|亚洲一区无码中文字幕|特级无码毛片免费视频播放▽|久久狠狠躁免费观看|国内精品久久久久久网站