淺談PHP的類型約束

前言

衆所周知,在 強類型 語言中,類型約束 是語法上的要求,即:定義一個變量的時候,必須指定其類型,而且之後該變量也只能存儲該類型數據。php

而咱們的PHP是弱類型語言,其特色就是無需爲變量指定類型,並且在其後也能夠存儲任何類型,固然這也是使用PHP能快速開發的關鍵點之一。可是在php的高版本語法中(PHP5起),在某些特定場合,針對某些特定類型,也是能夠進行語法約束的。segmentfault

介紹

自PHP5起,咱們就能夠在函數(方法)形參中使用類型約束了。設計模式

函數的參數能夠指定的範圍以下:數組

  1. 必須爲對象(在函數原型裏面指定類的名字);函數

  2. 接口;oop

  3. 數組(PHP 5.1 起);測試

  4. callable(PHP 5.4 起)。.net

  5. 若是使用 NULL 做爲參數的默認值,那麼在調用函數的時候依然可使用 NULL 做爲實參。設計

若是一個類或接口指定了類型約束,則其全部的子類或實現也都如此。code

注意:在PHP7之前,類型約束不能用於標量類型如 int 或 string。Traits 也不容許。

使用

下面是官方給的例子:

<?php
//以下面的類
class MyClass
{
    /**
     * 測試函數
     * 第一個參數必須爲 OtherClass 類的一個對象
     */
    public function test(OtherClass $otherclass) {
        echo $otherclass->var;
    }


    /**
     * 另外一個測試函數
     * 第一個參數必須爲數組 
     */
    public function test_array(array $input_array) {
        print_r($input_array);
    }
}

    /**
     * 第一個參數必須爲遞歸類型
     */
    public function test_interface(Traversable $iterator) {
        echo get_class($iterator);
    }
    
    /**
     * 第一個參數必須爲回調類型
     */
    public function test_callable(callable $callback, $data) {
        call_user_func($callback, $data);
    }
}

// OtherClass 類定義
class OtherClass {
    public $var = 'Hello World';
}
?>

函數調用的參數與定義的參數類型不一致時,會拋出一個可捕獲的致命錯誤。

<?php
// 兩個類的對象
$myclass = new MyClass;
$otherclass = new OtherClass;

// 致命錯誤:第一個參數必須是 OtherClass 類的一個對象
$myclass->test('hello');

// 致命錯誤:第一個參數必須爲 OtherClass 類的一個實例
$foo = new stdClass;
$myclass->test($foo);

// 致命錯誤:第一個參數不能爲 null
$myclass->test(null);

// 正確:輸出 Hello World 
$myclass->test($otherclass);

// 致命錯誤:第一個參數必須爲數組
$myclass->test_array('a string');

// 正確:輸出數組
$myclass->test_array(array('a', 'b', 'c'));

// 正確:輸出 ArrayObject
$myclass->test_interface(new ArrayObject(array()));

// 正確:輸出 int(1)
$myclass->test_callable('var_dump', 1);
?>

類型約束不僅是用在類的成員函數裏,也能使用在函數裏:

<?php
// 以下面的類
class MyClass {
    public $var = 'Hello World';
}

/**
 * 測試函數
 * 第一個參數必須是 MyClass 類的一個對象
 */
function MyFunction (MyClass $foo) {
    echo $foo->var;
}

// 正確
$myclass = new MyClass;
MyFunction($myclass);
?>

類型約束容許 NULL 值:

<?php

/* 接受 NULL 值 */
function test(stdClass $obj = NULL) {

}

test(NULL);
test(new stdClass);

?>

PHP7

標量類型聲明 (PHP 7)

標量類型聲明 有兩種模式: 強制 (默認) 和 嚴格模式。
如今可使用下列類型參數(不管用強制模式仍是嚴格模式):

  1. 字符串(string),

  2. 整數 (int),

  3. 浮點數 (float),

  4. 布爾值 (bool)。

它們擴充了PHP5中引入的其餘類型:類名,接口,數組和 回調類型。

<?php
// 強制模式
function sumOfInts(int ...$ints)
{
     return array_sum($ints);
}
 
var_dump(sumOfInts(2, '3', 4.1));

以上範例的運行結果會輸出:int(9)

要使用嚴格模式,一個 declare 聲明指令必須放在文件的頂部。這意味着嚴格聲明標量是基於文件可配的。 這個指令不只影響參數的類型聲明,也影響到函數的返回值聲明。

總結

以上就是PHP類型約束的大概簡介和使用方法了,在使用PHP進行開發過程當中,用到它的地方可能不是太多,咱們最常看見或用到類型約束的地方是在「依賴注入」的設計模式中,有興趣的能夠看下我這篇介紹依賴注入的文章:聊一聊PHP的依賴注入(DI) 和 控制反轉(IoC)

參考官方文檔:http://php.net/manual/zh/language.oop5.typehinting.php

相關文章
相關標籤/搜索