PHP7聲明標量類型以及強類型校驗講解

PHP7早在2015年就已經發布了,使用的人也是越來越多了,本篇文章我們要講的是PHP7如何聲明標量類型以及PHP7如何進行強類型校驗,不瞭解的同學可以看看哦!

 

標量類型聲明

PHP從PHP5.0開始已經有對支持class和interface參數類型聲明,PHP5.1支持array以及PHP5.4支持callable。這些類型聲明讓PHP在執行的時候傳入正確的參數,讓函數簽名具有更多的信息。

從PHP7開始,int、float、string和bool會被識別爲類型聲明,可用於函數返回值類型和參數類型聲明

<?php

function sum(int $a,int $b):string {
    return $a+$b;
}
var_dump(sum(1,2));

運行以上代碼正常
結果爲string(1) "3",弱類型校驗模式下如果參數不符合聲明類型,將會按照php的規則進行轉換

PHP7.1添加了可空類型的聲明方式並增加了void做爲函數返回值類型,強類型檢查模式下定義返回類型爲 void 的函數不能有返回值,即使返回 null 也不行:

declare(strict_types=1);

function returns_one(): void {
    return 1; // Fatal error: A void function must not return a value
}
function returns_null(): void {
    return null; // Fatal error: A void function must not return a value
}

 

此外 void 也只適用於返回類型,並不能用於參數類型聲明,否則會觸發錯誤:

function foobar(void $foo) {

// Fatal error: void cannot be used as a parameter type

}

可空類型聲明

可空類型主要用於參數類型聲明和函數返回值聲明。

主要的兩種形式如下:

function answer(): ?int{
    return null; //ok
}
function answer(): ?int{
    return 42; // ok
}

function say(?string $msg) {
    if ($msg) {

        echo $msg;

    }
}

 

從例子很容易理解,所指的就是通過 ? 的形式表明函數參數或者返回值的類型要麼爲指定類型,要麼爲 null。

此方法也可用於接口函數的定義:

interface Fooable {

    function foo(?Fooable $f);

}

但有一個需要注意的地方:如果函數本身定義了參數類型並且沒有默認值,即使是可空的,也不能省略,否則會觸發錯誤。

如下:

function foo_nullable(?Bar $bar) {}foo_nullable(new Bar); // 可行

foo_nullable(null); // 可行

foo_nullable(); // 不可行

但是如果以上函數的參數定義爲 ?Bar $bar = null 的形式,則第三種寫法也是可行的。因爲 = null 實際上相當於 ? 的超集,對於可空類型的參數,可以設定 null 爲默認值。

類函數中對於返回類型的聲明也不能被子類覆蓋,否則會觸發錯誤:

class Foo
{
    public function bar(): void {
    }
}
class Foobar extends Foo
{
    public function bar(): array { 
    // Fatal error: Declaration of Foobar::bar() must be  compatible with Foo::bar(): void

    }
}

嚴格校驗模式
strict_types/declare()指令

默認情況下,所有的PHP文件都處於弱類型校驗模式。新的declare指令,通過指定strict_types的值(1或者0),1表示嚴格類型校驗模式,作用於函數調用和返回語句;0表示弱類型校驗模式。

declare(strict_types=1)必須是文件的第一個語句。如果這個語句出現在文件的其他地方,將會產生一個編譯錯誤,塊模式是被明確禁止的。

類似於encoding指令,但不同於ticks指令,strict_types指令隻影響指定使用的文件,不會影響被它包含(通過include等方式)進來的其他文件。該指令在運行時編譯,不能修改。它的運作方式,是在opcode中設置一個標誌位,讓函數調用和返回類型檢查符合類型約束

<?php
declare(strict_types=1);

function sum(int $a,int $b):string {

    return $a+$b;

}
var_dump(sum(1,2));

以上代碼不符合函數的返回值類型聲明,將拋出TypeError的錯誤

<?php

declare(strict_types=1);

function sum(string $a,string $b):string {
    return $a+$b;
}
var_dump(sum(1,2));

以上代碼不符合函數的參數類型聲明,也會拋出錯誤

有一個例外的是,寬泛類型轉換是允許int變爲float的,也就是說參數如果被聲明爲float類型,但是它仍然可以接受int參數。

<?php

declare(strict_types=1);
function sum(int $a,int $b):float {
    return $a+$b;
}
var_dump(sum(1,2));

以上代碼運行正常

在這種場景下,我們傳遞一個int參數給到定義接受float的函數,這個參數將會被轉換爲float。除此之外的轉換,都是不被允許的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章