首頁 後端開發 PHP7 PHP 7.4中的類型屬性(Typed Properties)

PHP 7.4中的類型屬性(Typed Properties)

Nov 30, 2019 pm 01:32 PM
PHP 7.4

在PHP 7.4中加入了類型屬性,並對PHP的類型系統進行了重大改進。這些變更是完全可選的,並且不會破壞先前的版本。

在這篇文章中,我們將深入了解這個特性,但首先讓我們總結最重要的幾點:

● 它們自PHP 7.4起可用

##●●它們只在類別中可用,並且需要存取修飾符:public、protected或private;或var.

#● 除了void和callable之外,所有類型都是允許的

他們的實際情況是這樣的:

class Foo
{
    public int $a;
    public ?string $b = 'foo';
    private Foo $prop;
    protected static string $static = 'default';
}
登入後複製

#未初始化

在查看有趣的內容之前,首先要討論類型屬性的一個重要面向。

不管你第一眼看到的是什麼,下面的程式碼是有效的:

class Foo
{
    public int $bar;
}
$foo = new Foo;
登入後複製

即使$bar的值不是一個整數後,使一個物​​件Foo, PHP只會拋出一個錯誤時,$bar被存取:

var_dump($foo->bar);
Fatal error: Uncaught Error: Typed property Foo::$bar 
must not be accessed before initialization
登入後複製

從錯誤訊息中可以看到,有一種新的「變數狀態」:未初始化。

如果$bar沒有類型,則其值將為null。但是類型可以為空,因此無法確定是否設定了類型為空的屬性,或者只是將其忘記了。這就是為什麼添加了“uninitialized(未初始化)”的原因。

關於未初始化,要記住四件事:

● 無法讀取未初始化的屬性,這樣做將導致致命錯誤。

● 因為在存取屬性時會檢查未初始化狀態,所以可以使用未初始化的屬性建立對象,即使其類型不可為空。

● 您可以先寫入未初始化的屬性,然後再讀取它。

● 在類型屬性上使用unset將使其未初始化,而取消對非類型化屬性的設定將使其為null。

特別要注意,下面的程式碼是有效的,其中在建構物件之後設定了非初始化的、不可空的屬性

class Foo
{
    public int $a;
}
$foo = new Foo;
$foo->a = 1;
登入後複製

雖然僅在讀取屬性值時才檢查未初始化狀態,但在寫入屬性值時進行類型驗證。這意味著您可以確保任何無效類型都不會以屬性值的形式結束。

#預設值和建構子

讓我們仔細看看如何初始化鍵入的值。對於標量類型,可以提供一個預設值:

class Foo
{
    public int $bar = 4;
    
    public ?string $baz = null;
    
    public array $list = [1, 2, 3];
}
登入後複製

注意,如果類型實際上是空的,則只能使用null作為預設值。這似乎是顯而易見的,但是有些舊的行為帶有參數預設值,其中允許以下操作:

function passNull(int $i = null)
{ /* … */ }
passNull(null);
登入後複製

幸運的是,類型屬性不允許這種令人困惑的行為。

另請注意,物件或類別類型不可能有預設值。您應該使用建構函數來設定它們的預設值。

初始化類型化值的明顯地方當然是建構子:

class Foo{
    private int $a;
    public function __construct(int $a)
    {
        $this->a = $a;
    }
}
登入後複製

但也請記住我前面提到的:在建構子外部寫入未初始化的屬性是有效的。只要沒有從屬性讀取任何內容,就不會執行未初始化檢查。

#類型的類型

那麼究竟什麼可以輸入,如何輸入呢?我已經提到類型化屬性只在類別中有效(目前),它們需要一個訪問修飾符或var關鍵字在它們前面。

對於可用類型,除了void和callable之外,幾乎所有類型都可以使用。

因為void意味著沒有值,所以不能將其用於鍵入值是有意義的。 callable稍微有點差別。

可見,PHP中的「 callable」 可以這樣寫:

但也請記住我前面提到的:在建構子外部寫入未初始化的屬性是有效的。只要沒有從屬性讀取任何內容,就不會執行未初始化檢查。

看,一個「callable」在PHP可以這樣寫:

$callable = [$this, 'method'];
登入後複製

假設您有以下(無效)程式碼:

class Foo
{
    public callable $callable;
    
    public function __construct(callable $callable)
    { /* … */ }
}
class Bar
{
    public Foo $foo;
    
    public function __construct()
    {
        $this->foo = new Foo([$this, 'method'])
    }
    
    private function method()
    { /* … */ }
}
$bar = new Bar;
($bar->foo->callable)();
登入後複製

在本例中,$callable引用私有Bar::方法,但是在Foo的上下文中被呼叫。由於這個問題,決定不添加callable的支援。

不過,這沒什麼大不了的,因為Closure是一個有效類型,它將記住建構它的$this上下文。

順便說一句,這是所有可用類型的清單:

● bool

#● int

● float

##● string

● array

● iterable

● object

● ? (nullable)

● self & parent

● Classes & interfaces

#強制類型和嚴格類型

PHP是我們喜歡和討厭的一種動態語言,它將盡可能地強制轉換類型。假設您在期望整數的地方傳遞了一個字串,PHP將嘗試自動轉換該字串:

function coerce(int $i)
{ /* … */ }
coerce('1'); // 1
登入後複製

相同的原則也適用於類型屬性。

下面的程式碼是有效的,並將「1」轉換為1。

class Bar
{
    public int $i;
}
$bar = new Bar;
$bar->i = '1'; // 1
登入後複製

如果您不喜歡這種行為,可以透過聲明嚴格類型來停用它:

declare(strict_types=1);
$bar = new Bar;
$bar->i = '1'; // 1
Fatal error: Uncaught TypeError: 
Typed property Bar::$i must be int, string used
登入後複製

#類型差異和繼承

即使PHP 7.4引入了改進的類型差異,但類型屬性仍然不變。

這意味著以下內容無效:

class A {}
class B extends A {}
class Foo
{
    public A $prop;
}
class Bar extends Foo
{
    public B $prop;
}
Fatal error: Type of Bar::$prop must be A (as in class Foo)
登入後複製

如果上面的範例似乎並不重要,則應查看以下內容:

class Foo
{
    public self $prop;
}
class Bar extends Foo
{
    public self $prop;
}
登入後複製

在運行程式碼之前,PHP將在幕後用它所引用的具體類別來替換self。

这意味着在本例中会抛出相同的错误。处理它的唯一方法,是执行以下操作:

class Foo
{
    public Foo $prop;
}
class Bar extends Foo
{
    public Foo $prop;
}
登入後複製

说到继承,您可能会发现很难找到任何好的用例来覆盖继承属性的类型。

虽然我同意这种观点,但值得注意的是,可以更改继承属性的类型,但前提是访问修饰符也从private更改为protected或public。

以下代码有效:

class Foo{
    private int $prop;
}
class Bar extends Foo
{
    public string $prop;
}
登入後複製

但是,不允许将类型从可为空的类型更改为不可为空或反向的类型。

class Foo
{
    public int $a;
    public ?int $b;
}
class Bar extends Foo
{
    public ?int $a;
    public int $b;
}
Fatal error: Type of Bar::$a must be int (as in class Foo)
登入後複製

翻译:https://stitcher.io/blog/typed-properties-in-php-74

以上是PHP 7.4中的類型屬性(Typed Properties)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1665
14
CakePHP 教程
1423
52
Laravel 教程
1321
25
PHP教程
1269
29
C# 教程
1249
24