用php進行靜態類型編程,估計是我的一個心結。 依次有幾篇文章都記錄了我的一些探索: 通過指定函數/方法形參類型提高PHP代碼可靠性 http://www.cnblogs.com/x3d/p/4285787.html 用Yii框架中的collections體驗PHP類型化編程 http://www. ...
用php進行靜態類型編程,估計是我的一個心結。
依次有幾篇文章都記錄了我的一些探索:
- 通過指定函數/方法形參類型提高PHP代碼可靠性 http://www.cnblogs.com/x3d/p/4285787.html
- 用Yii框架中的collections體驗PHP類型化編程 http://www.cnblogs.com/x3d/p/php-typed-programming.html
從PHP 7 開始,PHP支持函數和方法的參數及返回值的標量類型標註,逐漸走出了這一步。
但數據傳遞的過程中,基礎的標量類型很多時候是不夠用的。比如參數太多的時候,一般用數組或對象的方式傳遞,二者中用得最多是數組 - 萬能的數組,但數組的結構不明確,在數據傳遞的過程中,對於DTO(Data Transfer Object,數據傳輸對象)相應數據結構的理解和驗證,往往需要額外花費不少時間和精力。在我看來,Hack 語言的Shape類型很好的解決了這個問題。
hack中Shape的用法如下:
type customer = shape('id' => int, 'name' => string);
function create_user(int $id, string $name): customer {
return shape('id' => $id, 'name' => $name);
}
function ts_shape(): void {
$c = create_user(0, "James");
var_dump($c['id']);
var_dump($c['name']);
}
ts_shape();
Output
int(0)
string(5) "James"
今天動手實現類似hack中的Shape定義,hack中shape本質上是一個數組。
Shapes 是一種特殊的別名類型,代表結構固化的數組 - 固定的鍵名和類型。定義的Shape可用於類型標註場合。
藉助於php的gettype函數,實現類似強類型的概念,不做類型casting。
支持php的基本類型:int、bool、float、string,及array、object、null。
基本用法:
class Customer extends Shape
{
public function __construct(array $data) {
parent::__construct(
['id' => self::int, 'name' => self::string, 'categories' => self::array],
$data
);
}
}
//數據訪問與數組一樣,只是一言不合就會拋異常,確保在開發階段,做好數據類型分析和轉換
$customer = new Customer(['id' => 102, 'name' => 'jimmy', 'categories' => [10, 21, 22]]);//如果categories寫成categories2,meta中定義的categories就會被填充一個對應的預設值。
$customer['id'] = 103; //如果傳'103'就會拋異常
var_dump($customer['id']);
var_dump($customer['categories']);
echo count($customer);
var_dump($customer->toArray());//PHP的array強轉還不支持魔術方法定製toArray行為,只能由用戶自行調用了
完整代碼的查看地址:https://github.com/web3d/lang/blob/master/src/AppserverIo/Lang/Shape.php