本文從 PHP 語言的 YII2 框架說起,簡單談一些技術的演變和發展脈絡。
YII2 這個框架是 PHP 語言生態下的一款 Web 應用框架。
有過 PHP 開發經驗的開發者都不會陌生,或多或少都聽說過,熟悉,至少接觸過。
回到始點 PHP 官方定位
PHP is a popular general-purpose scripting language that is especially suited to web development
PHP 官方的定義是基于輕型的 Web 應用,最典型的應用是 MVC。
YII2 初來乍到
在 2013 年,2014 年 YII2 剛剛發布的年份,YII2 被大家追逐的原因是
- 面向對象數據
- 包加載的擴展屬性
- 自帶 Gii 自動化生成工具
- 清爽的 View 界面和工具包
- API 序列化模型這幾個
我們返回頭再整體回顧下 YII2 框架,你會發現在 YII2 官方的默認模版中,View 層還是占有很大的比重的。
而最近幾年,前端技術演進迅猛,Web 開發都在使用前后端分離。
分離大部分內容是數據的業務控制和界面的顯示。
View 逐漸被前端框架,如 Vue 取代,YII2 也暴露出來它的劣勢。
在 YII2 社區中安裝 YII2 版本的討論中,經常有一個 View asset 擴展安裝的難題。
核心就是前端頁面元素與后端服務的耦合的問題,以及版本依賴的沖突。
相關命令
composer global require "fxp/composer-asset-plugin:*"
使用 YII2 構建 API
簡單概括
現在我們使用 YII2,就是在使用它構建 API 的能力。
看一看 YII2 官方文檔 列出來的 YII2 關鍵組成,基本上很多已經退出常見的使用場景。
找到了一個介紹 YII2 微框架,為服務接口而設計的 使用 Yii 作為微框架,
YII2 去掉預置的模版,去掉 View 功能,剩下的核心也就是這個了。
可擴展性
關于 YII2 這款框架,有兩個概念值得說明一下
組件和模塊
.YII2 的擴展性主要體現在組件(comments)的設計上
'components' => [
'request' => [
'cookieValidationKey' => 'dmpisthebest',
'parsers' => [
'application/json' => 'yii\web\JsonParser',
]
],
'cache' => [
'class' => 'yii\caching\FileCache',
],
'errorHandler' => [
'errorAction' => 'site/error',
],
'user' => [
'identityClass' => '',
'enableAutoLogin' => false,
],
]
YII2 種常見的組件 包括 user,seesion redis mongodb,log 等
感覺組件更適合做 infrastructure 的構建,而 module 則適合做業務的分離解耦
配置 YII2 帶來的耦合性
我們簡單分析 YII2 的主配置文件,
很容易了解到 YII2 是通過模塊(module),組件(components)來啟動和項目功能的。除必須的模塊和組件外,組件和模塊可以按需加載。
雖然組件和模塊為擴展性提供了便利,引用它們使用的配置,會造成入口 index.php 自動加載的 main.php 文件復雜臃腫,難以維護和閱讀。
解決耦合可以從以下幾個方面的嘗試
根據環境分拆配置文件
根據環境,加載不同的文件,可以 通過域名,變量等方式確定環境,進而分離配置文件。
根據組件分拆配置文件,實現組件和模塊的按需加載。
復制優于依賴
Alittle copyiing is better than a litter dependcy
有時候不一定要優先追求共享代碼,應該有一部分復制冗余。公用代表著多處使用,和依賴耦合。復制雖然增加了復制的成本,卻獨立自由。
怎么理解這句話?
我們以 YII2 工程為例,官方推薦的 Advanced 模版中有一個公共工程 common
那我們是不是應該把項目中可以共用的數據層都放到 common 里?
如上圖,passport 和 admin 兩個模塊,如果都涉及同一張 User 表,依據復制優于依賴的原則,沒有必要公用一個 User 類,可以單獨存放為兩個 User 類,用命名空間做隔離。更何況因為模塊不一樣,即使同一個數據表對象,相關的數據操作也會不一樣。
/**
* @inheritdoc
*/
public function init()
{
if (!$this->accountId)
throw new InvalidConfigException('accountId required.');
if (!$this->secretKey)
throw new InvalidConfigException('secretKey required.');
}
PHP 如何做單元測試
這個可以作為一個面試題與候選者溝通,但是我下邊這段話,不適合作為答案。
當然會有一些單元測試組件,比如 YII2 下的 Codeception,PHPUnit 進行數據 Mock??蓪嶋H情況呢,程序直接用 var_dump,REST 接口測試程序即可調試,達到單元測試的目的。
這就是 最簡單的理論和實際的出入,理論結合實踐的實話。
總結
看看程序語言的發展脈絡,以及前后端發展的變革,可以總結出兩個詞:演變和趨勢。
演變和趨勢
在應用程序開發中,前端這個職位是從后端細化和演變而來的,前后端分離和獨立就是技術的趨勢。
包括技術層面的技術選擇和生態
職位層面的前端工程師和后端工程師
部門層面的前端部門和后端部門。
演變底層邏輯是萬變不離其宗,趨勢代表著先進的技術就是先進的生產力。
本來想寫一篇關于重新定位 YII2 的文章,最后發現本文的重點已經不是 YII2 ,而是這種變化趨勢對于相關決策的度量參考。
唯有改變思路,才有出路。用發展的眼光去追技術。