解決方案
在 Facebook 的規模下,PHP 的極限帶來嚴重問題:數千名工程師每天發布新程式碼兩次,但對空物件呼叫方法,或猜測複雜 API 的方法名稱,只會在執行時產生錯誤,而這個語言也讓工具缺乏可供內省的結構。這種動態語言讓編輯後重新整理的循環保持快速,卻沒有提供早期安全網;而傳統的靜態型別語言雖能換來檢查,代價卻是犧牲迭代速度——重寫則會丟棄 Facebook 在 PHP 及其函式庫上的投資。
Hack 於 2014 年 3 月 20 日作為 HHVM 執行環境的一部分發布,透過維持 PHP 超集的身分,解決了這個兩難。大多數 PHP 檔案本來就是有效的 Hack,因此工程師可以為某個函式加上型別標註,而下一個函式維持動態,靜態與動態型別的程式碼即使在同一個檔案內也能無縫互通。Hack 新增了泛型、可空型別、型別別名、集合與 lambda 運算式,HHVM 則在執行時強制檢查已標註的傳回型別與參數型別,這也讓其 JIT 能安全地信任標註以進行最佳化。
為了維持快速的 PHP 工作流程,團隊將型別檢查器架構成本地伺服器,監看檔案系統並將整個程式碼圖保存在記憶體中;典型檢查在 200 毫秒內完成,很少超過一秒。由於轉換是細粒度且可選擇加入的,工程師自願轉換了自己大部分的程式碼,自行開發的程式碼修改工具自動處理其餘部分,而在過去一年內,幾乎整個 Facebook PHP 程式碼庫都已遷移到 Hack。
同一項發布也以 HHVM 為名義,將 Hack 與轉換工具開源,這些工具將繼續在 Hack 旁邊執行未經修改的 PHP,並邀請開發者參加下個月在門洛帕克園區舉行的 Hack Developer Day。該發布在出現當天於 Hacker News 獲得 576 點與 415 則留言。
達成了什麼
將漸進式靜態型別附加到 PHP 本身,讓安全性一個函式一個函式地擴散,而非一次全部到位
為何奏效
超集相容性意味著無需重寫,也無需一次性大規模遷移:既有 PHP 檔案持續執行,HHVM 仍是 PHP 執行環境,第三方 PHP 函式庫在整個過程中仍可使用。
以函式為單位的細粒度讓安全性依各團隊自己的步調擴散,因為未標註的程式碼維持動態,不會阻擋整個檔案或模組進行轉換。
監看檔案系統的檢查器伺服器將回饋維持在 200 毫秒內,因此靜態型別並未加重讓 PHP 迭代快速的編輯後重新整理循環。
工程師選擇為自己的程式碼加上標註,程式碼修改工具處理重複的其餘部分,因此數百萬行的程式碼庫在一年內完成轉換,而非等待專責的遷移團隊。
可借鏡之處
不要為了獲得安全性而重寫:讓語言接受舊程式碼,讓新紀律一次一個函式地擴散,並讓檢查快到絕不中斷工作流程。
後續發展
Hack 及其程式碼修改工具以 hacklang.org 為名,作為 HHVM 的一部分開源,Facebook 表示 HHVM 將繼續作為 PHP 執行環境,朝 PHP-5 對等性邁進,讓第三方 PHP 程式碼能與 Hack 並行執行。該發布於 2014 年 3 月 20 日在 Hacker News 獲得 576 點與 415 則留言,Facebook 並計畫下個月在其門洛帕克園區舉行 Hack Developer Day。在 Facebook 內部,遷移實際上已經完成:經過約一年的自發採用加上自動化重構工具,幾乎整個 PHP 程式碼庫都執行 Hack。
追溯依據
參考來源
- Hack: a new programming language for HHVM Engineering at Meta · engineering.fb.com ·
- Hacker News discussion: Hack: a new programming language for HHVM Hacker News · news.ycombinator.com ·