衆所周知,在 強類型 語言中,類型約束 是語法上的要求,即:定義一個變量的時候,必須指定其類型,而且之後該變量也只能存儲該類型數據。php
而咱們的PHP是弱類型語言,其特色就是無需爲變量指定類型,並且在其後也能夠存儲任何類型,固然這也是使用PHP能快速開發的關鍵點之一。可是在php的高版本語法中(PHP5起),在某些特定場合,針對某些特定類型,也是能夠進行語法約束的。segmentfault
自PHP5起,咱們就能夠在函數(方法)形參中使用類型約束了。設計模式
函數的參數能夠指定的範圍以下:數組
必須爲對象(在函數原型裏面指定類的名字);函數
接口;oop
數組(PHP 5.1 起);測試
callable(PHP 5.4 起)。.net
若是使用 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); ?>
標量類型聲明 (PHP 7)
標量類型聲明 有兩種模式: 強制 (默認) 和 嚴格模式。
如今可使用下列類型參數(不管用強制模式仍是嚴格模式):
字符串(string),
整數 (int),
浮點數 (float),
布爾值 (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