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。除此之外的轉換,都是不被允許的。