開發者回憶:PHP早已不是十年前的模樣
開發者 Brent 發布了一篇文章,詳細介紹了2019年的PHP是怎麼樣的。Brent承認PHP當前仍然存在一些問題,比如許多核心函數仍然有不一致的方法簽名、配置設置還是令人困惑,但是以他自己的開發經驗來看,他認為PHP是Web開發的絕佳選擇,使用PHP ,他可以創建可靠、可維護和高質量的應用,並且自己與客戶對最終結果都滿意。
文章中Brent關注於PHP這些年來發展得好的一面,他通過幾下幾點,說明“ PHP不再是十年前那一門糟糕的語言了 ”:
- PHP 正在積極開發,每年都會發布新版本
- PHP 5 之後性能在不斷提高
- 有非常活躍的框架、包和平台組成的語言生態
- PHP 在不斷發展,過去幾年中添加了許多新功能
- 各種開發工具在過去幾年中已經成熟,並且保持增長
PHP 正在積極開發,每年都會發布新版本
當前PHP 版本是去年12 月份發布的 7.3,7.4 預計在今年年底發布,而PHP 8.0 將是7.4 之後的下一個版本。
自從5.X 時代以來,核心團隊希望每年發布一個新版本,在過去四年中他們成功維護了這麼一個發布週期。通常每個新版本都會得到官方兩年時間的積極支持,之後有一年僅提供安全修復,其目的是激勵PHP 開發人員盡可能保持更新。
更加具體的發布與維護週期可以查看PHP 官網的介紹:
看到上邊這個表,你可能會發現版本號從5 跳到了7,那PHP 6 去哪裡了?
其實早在2005 年,PHP 社區就發起了PHP 6,但由於實現Unicode 面臨的困難太大,項目最終流產,PHP 官方沒有發布PHP 6 GA,並且在 2010 年將PHP 6 取消。雖然PHP 6 項目取消了,但其大量已實現功能集成到了 PHP 5.X 中,包括OOP 方面的改進,使得PHP 從面向過程跨越到面向對象。
PHP 6 被取消了,但是之前對這個主要版本的研發都是以PHP 6 的名義進行的,所以許多參考資料與書籍都是用“PHP 6”來指代該版本。官方擔心這在放棄PHP 6 之後會引起混亂,於是乾脆不使用PHP 6.X 版本號,直接從5 跳到7。
詳情可以查看官方說明:https://wiki.php.net/rfc/php6
PHP 5 之後性能在不斷提高
PHP 7.0 中,PHP 核心部分完全重寫,帶來了最新的Zend 引擎,使得PHP 性能提升了兩到三倍。
作者引用了 https://kinsta.com/blog/php-benchmarks 的基準測試來說明這一點,指出自7.0以來,PHP性能一直在提升,PHP Web應用與其它語言的Web框架相比在一些情況下性能好很多。但他也表示:“當然PHP框架不會勝過C與Rust,但比Rails或Django好得多,與ExpressJS相當。”
有非常活躍的框架、包和平台組成的語言生態
提到PHP 的框架,不得不說WordPress,但是作者表示WordPress 絕對不代表當前的PHP 生態:“PHP 框架再也不僅僅只有WordPress 了”。
當前PHP 中有兩個主要的Web 應用開發框架:Symfony 與Laravel,還有Zend、Yii、Cake 與Code Igniter 這些,此外還有不少較小的框架。
Symfony與Laravel都擁有龐大的包和軟件生態,包括admin面板和CRM、獨立軟件包、CI、分析器、Web socket 服務器、隊列管理器與支付集成等。
此外,近幾年PHP 異步框架也興起了,Swoole、Amp 與ReactPHP 是其中的佼佼者,它們是用PHP 或其它語言編寫的框架和服務器,用來運行真正的異步PHP。
作者認為衡量PHP生態當前狀況的一種方法是查看 Packagist 這個PHP主要軟件包存儲庫的數據。通過以下趨勢圖,可以發現軟件包數量呈指數增長,並且當前錄入軟件包有223 217個,總的安裝量達到了14 827 204 847,PHP生態已不再像以前那麼弱小。
各種版本的可用軟件包的數量
每月包被安裝數
PHP 在不斷發展,過去幾年中添加了許多新特性
儘管async 與await 這兩個呼聲極高的特性還沒有實現,但是PHP 這幾年新特性不斷出現,語言本身得到了各方面的改進。
下邊列出了一些關注度比較高的PHP 新特性:
短閉包,也稱為箭頭函數,這是一種在PHP中編寫較短函數的方法。將閉包傳遞給array_map或array_filter等函數時,它可以發揮極大的作用。
// A collection of Post objects $posts = [/* … */];$ids = array_map(fn($post) => $post->id, $posts);
空合併運算符,它類似於三元運算符,但左邊的操作數行為類似於isset,而不是僅使用其布爾值。這使得此運算符對數組特別有用。它同時可在未設置變量時分配默認值。
$undefined ?? 'fallback'; //'fallback'$unassigned;$unassigned ?? 'fallback'; //'fallback'$assigned = 'foo';$assigned ?? 'fallback'; //'foo'' ' ?? 'fallback'; //'''foo' ?? 'fallback'; //'foo''0' ?? 'fallback'; //'0'0 ?? 'fallback'; //0false ? ? 'fallback'; //false
Trait 是一種重用代碼的機制,它可以減少單繼承的某些限制。Traits 與類組合的語義定義了降低複雜性的方式,並避免了與多重繼承和Mixins 相關的典型問題。
Trait 類似於類,但僅用於以細粒度和一致的方式對函數進行分組,它是對傳統繼承的補充,可以實現行為的橫向組合,類成員應用不需要繼承。
<?phptrait ezcReflectionReturnInfo { functiongetReturnType(){ /*1*/ } functiongetReturnDescription(){ /*2*/ }}classezcReflectionMethodextendsReflectionMethod{ useezcReflectionReturnInfo; /* ... */}classezcReflectionFunctionextendsReflectionFunction{ useezcReflectionReturnInfo; /* ... */} ?>
屬性類型化,類變量可以定義類型,比如:
classA{ public string $name; public Foo $foo;}
擴展運算符,這是一種新語法,可以直接在調用中解壓縮參數,比如:
call_user_func_array([$db, 'query'], array_merge(array($query), $params));
直接用新語法可擴展出數組$params:
$db->query($query, ...$params);
- JIT compiler:PHP 8確認支持JIT
JIT 是一種編譯器策略,它將代碼表述為一種中間狀態,在運行時將其轉換為依賴於體系結構的機器碼,並即時執行。在PHP 中,這意味著JIT 將為Zend VM 生成的指令視為中間表述,並以依賴於體系結構的機器碼執行,也就是說託管代碼的不再是Zend VM,而是更為底層的CPU 。
Foreign Function Interface,外部函數接口,它允許從純腳本語言調用C 函數、使用C 數據類型,從而更有效地開發“系統代碼”。對於PHP,FFI 開闢了一種使用純PHP 編寫PHP 擴展和綁定到C 庫的方法。
匿名類,用於創建簡單的一次性對象:
<?php// Pre PHP 7 codeclassLogger{ publicfunctionlog($msg){ echo $msg; }}$util->setLogger(new Logger());// PHP 7+ code$util->setLogger(newclass{ publicfunctionlog( $msg){ echo $msg; }});
聲明返回類型:
<?phpfunctionsum($a, $b): float{ return $a + $b;}// Note that a float will be returned.var_dump(sum(1, 2));?>
嚴格模式:
<?phpdeclare(strict_types=1);functionsum($a, $b): int{ return $a + $b;}var_dump(sum(1, 2));var_dump(sum(1, 2.5));?>
使Libsodium 成為核心擴展,Libsodium 是一個現代加密庫,由安全專家精心選擇的加密算法組成,以避免側信道漏洞。
生成器,提供了一種簡單、無樣板實現迭代器的方法。
各種開發工具在過去幾年中已經成熟,並且保持增長
最後一部分,作者分析了當前PHP 開發工具也在不斷成熟,並且保持增長。
他以靜態分析器為例,比如 Psalm、Phan 與 PHPStan,這些工具將靜態分析PHP代碼並報告任何類型錯誤與可能存在的bug。在某種程度上,它們提供的功能可以與TypeScript的相媲美,但是因為PHP現在不提供轉換(transpile),所以不允許使用自定義語法。這意味著PHP開發需要依賴文檔,但其實PHP的創造者Rasmus Lerdorf曾經提到了向核心添加靜態分析引擎的想法。
受到JavaScript社區的啟發,目前PHP也有在進行轉換的相關研發,比如項目 Pre,它允許新的PHP語法轉換為普通的PHP代碼。雖然這個想法已經在JavaScript中被證明可行,但作者認為在PHP中,只有先提供了適當的IDE和靜態分析支持,它才有可能實現。
講完了PHP 當前的這些變化,作者最後沒有以“PHP 是世界上最好的語言”作結語,相反,他是這樣說的:
All that being said, feel free to still think of PHP as a crappy language… I can say in confidence that I enjoy working with it.
話雖如此,但是還要繼續認為PHP 是蹩腳的語言那也是可以的。我可以很自信地說我喜歡PHP。