php – Type Hinting 類型提示
雖然歸類 PHP 為弱型別,不過在做 class 或 function 參數傳遞的時候還是可以做類型提示的約束喔!其實從 php 5.1 就已經可以有這種功能了,只是普遍都不流行使用,畢竟弱型別只要有一套判別技巧,是非常快速開發的,懂得運用的話並不會造成太大的困擾。因為可以更專注在應用層面。
本身已經有型別約束的功能了,參考官網介紹 http://php.net/manual/en/language.oop5.typehinting.php
但是我們最常遇到的 int 與 string 是沒辦法去做判別提示的。畢竟很多時間,我們是不太需要知道數字 1 是否等於文字 1,真的有須要去做判別,可以配合 === 使用。當然如果希望能明確識別 1 與 “1”,官網下面的網友已經貢獻出程式碼了,我這裡稍微做了修改美化
class Typehint { private static $TYPEHINT_PCRE = "/^Argument (\d)+ passed to (?:(\w+)::)?(\w+)\(\) must be an instance of (\w+), (\w+) given/"; private static $Typehints = array( 'bool' => 'is_bool', 'int' => 'is_int', 'float' => 'is_float', 'string' => 'is_string', 'resrouce' => 'is_resource' ); private function __construct() {} public static function initializeHandler() { set_error_handler('Typehint::handleTypehint'); return TRUE; } private static function getTypehintedArgument($ThBackTrace, $ThFunction, $ThArgIndex, &$ThArgValue) { foreach ($ThBackTrace as $ThTrace) { // Match the function; Note we could do more defensive error checking. if (isset($ThTrace['function']) && $ThTrace['function'] == $ThFunction) { $ThArgValue = $ThTrace['args'][$ThArgIndex - 1]; return TRUE; } } return FALSE; } public static function handleTypehint($ErrLevel, $ErrMessage) { if ($ErrLevel != E_RECOVERABLE_ERROR) return FALSE; if (!preg_match(self::$TYPEHINT_PCRE, $ErrMessage, $ErrMatches)) return FALSE; list($ErrMatch, $ThArgIndex, $ThClass, $ThFunction, $ThHint, $ThType) = $ErrMatches; if (!isset(self::$Typehints[$ThHint])) return FALSE; $ThBacktrace = debug_backtrace(); $ThArgValue = NULL; if (!self::getTypehintedArgument($ThBacktrace, $ThFunction, $ThArgIndex, $ThArgValue)) return FALSE; if (!call_user_func(self::$Typehints[$ThHint], $ThArgValue)) return FALSE; return TRUE; } }
在全域的地方添加
Typehint::initializeHandler();
接著可以測試一下囉
function testbool(bool $string) { echo $string; } function teststring(string $string) { echo $string; } function testinteger(int $integer) { echo $integer; } function testfloat(float $float) { echo $float; } function testarray(array $ary) { echo "TRUE"; } function testobject(stdClass $ary) { echo "TRUE"; } //使用布林 testbool(true); //使用字串 teststring("123"); //出現警告 must be an instance of string, integer given //使用物件 $param = array(); testobject($param); //出現警告 must be an instance of stdClass, array given