今天這篇文章跟大家比較一下ThinkPHP和Drupal,透過它們看中外軟體業現狀,看看國內的開源環境!
住房、結婚、醫療、教育、養老每一個都是一座大山,「搞錢」必須是頭等重要的大事,誰有空搞開源?於是僅兩個核心開發者打造的ThinkPHP成為了很多人的希望,而另外一邊,沒有“程式設計師是吃青春飯的”,開源軟體社群聚會上常常見到五六十歲的人還在眼中帶光的談論技術,他們尋找生命的意義,不被生計太多打擾,將一生的積累注入到開源,他們夢想自己所做的能照亮世界,將人生化做偉大的作品伴隨人類文明流傳下去,於是Drupal被萬眾捧出,並急速駛向星辰大海。本文講述了一個憂傷的故事,思考著看同種文字的人們該何去何從,這個故事應被更多人知道。
#將ThinkPHP和Drupal(翻譯成中文為「水滴」的意思)放在一起聊會讓很多開發者感到好奇,但從中外軟體生態發展來看,這真的是一個好的討論起點,本文對這兩個系統在各方面都做了一些對比,但對比不是寫作本文的主要目的,主要是分享中外軟體產業的不同,以及由此引發的一些思考,幫助開發者規劃職涯,為IT決策者提供決策依據。
這兩個系統都是開源、免費的PHP應用,首先做個簡單介紹:
#ThinkPHP:
產品定位:PHP開發框架,開發者在此基礎上繼續發展建構自己的應用系統
開發機構:由國內「上海頂想資訊科技有限公司」開發
創辦人:劉晨,沒有太多資料,百度查詢為開源軟體資深顧問,資深PHP程式設計師,看雲CEO,超過15年的互聯網產品開發和管理經驗,主要研究領域包括Web應用架構和開發,產品用戶體驗設計,致力於國內的開源事業
發展時間:最早誕生於2006年初
開源協定: Apache 2
官網位址:http://www.thinkphp.cn /
使用者群體:中國國內小微型企業,在國內開發者圈中具有較高知名度,其官網自我描述為「是國內最有影響力的PHP框架和先驅者!」
著名案例:56群組、聯想問吧、中青旅開心遨遊、寶礦力水特、星巴克、美特斯邦威的邦購商城、TCL的線上商城、新浪微壇,澳星、中車友科技等
團隊規模:沒有官方數據,但框架的每個文件有作者信息,據此統計一共有7人,其中主要開發者有兩人(貢獻90%以上代碼),這些資料不包括社區生態圈的貢獻開發者,依據企查平台對頂想公司查詢結果顯示,公司規模小於50人,參保人數3人
系統文件:按目前的6.0.7版本算,初裝檔案數569個,佔用空間2.41MB
#Drupal:
產品定位:完整的後端系統(後端資料與控制中心),用於APP、小程式、網站、物聯網等的後端開發
開發機構:全球兩百多個國家共建,Drupal基金會組織的非營利開源社區
創辦人:最初由比利時的Dries Buytaert博士發起,Dries 2008年的大學博士論文是《Java應用程式效能分析與優化分析技術》,Java的發明者詹姆斯‧高斯林(James Gosling)是其博士答辯委員會的成員,Dries個人主頁地址https://dri.es/about
發展時間:最早誕生於2000年
開源協議:GPL 2.0
官網網址:https://www.Drupal.org/
用戶群:全球各國的企業、政府機構、大學、個人等,其中世界五百大企業市場佔有率超過80%,著名IDE:phpstorm直接整合了Drupal專案新建
著名案例:國內有:華為、京東、百度、騰訊、清華、北大、貴州市政府站群、真功夫等,國外有:特斯拉、Google、本田、高通、聯合國、歐盟、哈佛大學、麻省理工大學、迪士尼、NASA、輝瑞製藥等
團隊規模:
擁有全球最大、最活躍的開源社區,核心開發者1,800餘人,處於活躍狀態的貢獻者(程式碼、文件、設計等人員)共有超過12萬人,其中中國分社區兩千萬人,主力推動公司Acquia員工超過1100人。目前平均每週產生1300次左右代碼提交。
系統檔案:以目前的9.1.7版本算,初裝檔案數18770個,佔用空間71.2MB
為什麼是ThinkPHP和Drupal:
一個是中國國內的流行框架,一個是國際流行的完整後端系統(也是目前世界上最強大靈活的系統,沒有之一),從它們的體量看這完全不在一個重量級,從其市場定位來看,也沒有比較的意義,但探索它們對了解中外軟體生態具有重要意義,此外如果直接告訴你ThinkPHP能做的事情,Drupal都能做,而且還更加優雅和簡潔呢?事情是不是就變的很有趣了,繼續。
通常使用Drupal的國內開發者都是有很多年經驗的開發老手,是伴隨時代從各種系統一步一步淌出來的,他們一定知道或多少了解ThinkPHP,但使用ThinkPHP的開發者卻不一定了解Drupal,使用ThinkPHP的開發者選擇ThinkPHP的理由一般是:框架較底層PHP進一步的提供了常用基礎,靈活自由,和對帝國CMS這樣的系統進行二次開發相比,不受限制,能夠隨意實現自己的功能,但是在Drupal面前,事情就變的不一樣了,可能會讓開發者有如獲至寶的感覺,在此需要先簡要介紹一下Drupal的系統架構,整個Drupal系統是分層建設的:
最底層:
是框架層,基於流行的Symfony框架,Symfony可謂是PHP的行業標準,是世界最著名的框架,另一個著名的PHP框架Laravel本身很多部分也都是基於或來自Symfony,懂得Symfony框架的開發者可以很快上手開發Drupal,Symfony框架的作者法比安是一個傳奇人物,其另一個廣為人知的作品是Twig模板引擎,該引擎也用在Drupal中,Drupal是Symfony最著名的案例,其官網將Drupal列在第一位,Drupal社群也參與Symfony的程式碼貢獻。
第二層:
是數據層,以實體為代表,向上提供各種數據,資料庫封裝即屬於該層,ORM概念以及ThinkPHP中的模型概念類似於實體概念在很早很早時期的樣子
第三層:
應用層,開發者在這一層處理各種業務邏輯
#這裡需要注意開發者在使用Drupal時,不一定要一層一層往下調用,而是可以跨越,直接去面向某一層,所以當直接面向框架層開發時,就可以將整個系統當做框架來使用,就像ThinkPHP開發者直接使用ThinkPHP框架一樣,這就是為什麼說ThinkPHP能做的Drupal都能做的原因,所不同的是Drupal採用Symfony框架,題外話ThinkPHP深受Symfony影響,甚至直接採用了其部分組件,許多方面高度借鑒了Symfony框架(任何創造者都值得尊敬,因此不用「抄襲」這個詞,而用「借鑒」),主幹流程幾乎相同,但在成熟度和細節上相差甚遠,這種差距舉個例子來圖像的說明:
當人類先祖在結繩計數的那個時代,一個果子就是一個果子,一條魚就是一條魚,當從一個個具體事物中抽像出背後的數字“1”時,人類就面臨了一次巨大的飛躍,此刻的意義不亞於火的使用,進而發明數字、數學等,在時間和空間上,人類一直處於對世界的不停探索、抽象之中,無數次累積才有了現今的文明,可以說抽象程度越高,代表越強,越直達本質。
許多很棒的作品都需要巨大的人力和時間去積累,那麼ThinkPHP和Symfony之間,或者說ThinkPHP和Drupal之間積累的差距有多大呢?這裡可以直接果斷的告訴你是小學和大學之間的差距,中間還隔著國中、高中,主要原因在於社區規模、生態和時間上。 ThinkPHP和Symfony同為框架,是最直接的競爭者,ThinkPHP要有存在的必要就需要一條自主創新的路,卻又大量借鑒Symfony,這是一件非常尷尬的事情,作為開發者為什麼不直接使用Symfony呢?同等級的CI架構(CodeIgniter)就完全自主發展,在許多全球排名中都看不到ThinkPHP的影子,但在國內,你可以在許多招募資訊中看到ThinkPHP的影子,這是個很奇特的現象,因為ThinkPHP是個十足的地方性產品,連註釋文檔都是中文,本文也正是基於此才選擇了ThinkPHP來作為研究中外軟體狀態的起點。
何為好系統?我們需要什麼?
俗話說工欲善其事必先利其器,這裡列出幾個點來說明一個優秀的系統應該具備什麼特性,下文我們將以此來對比ThinkPHP和Drupal:
完備性:
#所謂完備性你可以認為是某個工具或元件被設計出來已經充分考慮到了所有的情況,例如PHP原生提供的字串截斷函數會把UTF-8字元截斷,產生亂碼,而你設計了一個截取函數,不但不會這樣,還不會截斷英文單詞,還考慮到了不截斷HTML中的標籤,那麼你這個工具就比PHP原生函數更加完備,一旦發現有滿足不了的用列就需要改進以提高完備性,Drupal很多地方的設計是「完備」的,儘管Drupal也在持續探索和進化,但這種完備程度遠超ThinkPHP,舉個例子,Drupal的路由系統可以天然支援基於域名、協定、HTTP方法、資料格式、選項等進行路由,在都匹配的情況下有優先級分級,而這些是ThinkPHP不完全具備的,這種組件設計上的完備依賴於對事務本質認知的深度和大量開發經驗,完備性讓人類站在前人的基礎上繼續前進。
標準化:
標準化是大規模協作的前提,系統分層結構、跨系統通訊、解耦組件等都離不開標準化,Drupal完全面向RFC文檔,而不是自成體系,在註釋或討論中經常看到對RFC的引用,RFC文檔是IT互聯網的基石,類似在產品上常見的國家標準,常被用戶忽略,但又異常重要。
完整性:
合作分工,當把發展的足夠完備的組件湊到一起,大家都來使用它們,這就構成了完整性,然後人們不必自己再重複造輪子,突破內卷,完整性也會反過來促使完備性的提高,Symfony和Drupal就以組件和模組的方式來解決完整性問題。
低耦合性:
系統設計各元件間需要盡可能解耦,這樣就能給各元件更多的發展提高的空間,不好的元件也便於替換,Drupal採用模組化設計,連核心都是模組化的,使用者可以在使用者空間中替換任何核心文件,而不直接修改,避免功能不足和阻礙升級,相對而言ThinkPHP耦合較緊。
掌握邊界:
一個好的系統勢必是分寸拿捏得當的系統,但這真的有點難,且仁者見仁智者見智,總的來看大方向或主幹系統必須是簡潔的,這裡舉一個例子,在ThinkPHP中支援以路由參數決定路由控制器,即:Route::get(':action/blog/:id', 'Blog/:action' );,而Drupal不允許這樣做,實現類似功能時通常採用代理控制器實現,簡而言之即該效果不應該在路由層面實現,而應該在控制器層面實現,這樣使得路由系統更加簡潔,系統架構更加清晰,這種思想貫穿Drupal,使得Drupal系統主幹十分簡單乾淨,當你要某個細化功能時,首先進入對應大支流再進入到不同的細化支流當中,是不是像一顆樹?但你比較喜歡哪種方式呢?
簡潔性:
大道至簡,系統需要流程清晰,呼叫統一,規則一致,不允許有另外,或盡量避免另外,這樣的好處是容易新人學習,追蹤、排查都很方便。
生命力:
系統的生命力也在於永續性,生態圈和開發者就是系統的養料,下文還會講到,這裡略過。
對比ThinkPHP和Drupal:
ThinkPHP和Drupal相比總的來說,在於ThinkPHP抽象程度不足,累積不足,這是根本上的不足,它像一個孩子,Drupal是一個經歷歲月的成年人,懂得更多,知道事物背後蘊含的通用道理,做的也更進一步,假設我們是在建造一棟大廈,ThinkPHP提供了混凝土、磚塊、鋼筋等等建築基礎材料,開發者需要去探索如何修建,如何設計等建築學問題,而Drupal不但提供了基礎材料,還附帶了施工隊和設計院,很多時候你只需要說出你要什麼樣感覺和功能的大廈就行了(你遇到的需求,通常已經有人遇到過,形成了數量龐大的貢獻模組,安裝即可),當然如果你有興趣,你也可以參與修建的過程得到你自訂的結果。
本章在技術架構層面上來比較二者,如果你不是開發者,或者對具體技術不感興趣,可以直接跳過本章,接著看下一章,這裡都以當前各自最新的版本ThinkPHP 6.0.7和Drupal 9.1.7,由於篇幅有限,僅選擇部分重要內容進行比較:
##事件:
在ThinkPHP中將事件定位為替代原來的行為和Hook機制,由此可見作者並沒有認識到事件和鉤子之間的本質區別,相同點都是用第三方代碼來介入當前邏輯的處理,但在這個大前提下鉤子重參與,事件重通知,它們在數量和性質上都有很大不同,ThinkPHP將其混為一談,而Drupal認識的更加本質,由於ThinkPHP對“事件”概念的認識不足也導致實作上鬆散複雜,且功能上有重大不足,例如ThinkPHP事件沒有優先級概念,這在有順序要求的情況下至關重要,同時也沒有事件傳播終止機制,又比如ThinkPHP可以不要求實現事件類,實際上要處理事件通常必須要有參數傳遞,並且需要將處理結果回饋給事件發源地,因此事件類別是必須的,ThinkPHP非常初淺,而Drupal中統一採用事件派發器服務處理所有事件,對訂閱器和偵聽器也無特殊限制,在系統任何地方處理事件相關邏輯只需要面對事件派發器服務即可
中間件:
在ThinkPHP和Drupal中都有「中間件」概念,但二者定位有很大不同,在ThinkPHP里中間件實現的功能,在Drupal中是由事件派發器負責的,比如ThinkPHP文檔提到中間件主要用於攔截或過濾應用的HTTP請求,這在Drupal中是派發請求事件做的事情,此外還有路由中間件、控制器中間件都是如此,它們對應路由事件、控制器事件,而Drupal中的中間件主要作用是將HTTP處理核心由一個變成多個,在邏輯架構上Drupal要比ThinkPHP優雅和清晰很多,這也是ThinkPHP對事件機制理解不足導致的,這讓系統結構雜亂了,為將來的升級埋藏了包袱
入口檔案:
兩者的入口檔案都很簡單,邏輯也比較類似,差異主要有三點:
1.Drupal直接在入口文件中向處理核心注入請求對象,從字面上直接體現“任何web系統都是將請求轉化為響應的系統”這一理念,而ThinkPHP的HTTP服務的run方法雖然也可以,但沒有在入口處體現,但這點沒什麼本質區別,區別大的是ThinkPHP缺乏對「子請求」功能的支持,即係統運行過程中向自己再提交請求進行處理的能力,不需要跳出系統再回來,此功能對系統架構影響很大(貫穿整個體系,子請求除不能影響到主請求的環境狀態外還要考慮效能),此一點最能看出Drupal的系統架構比ThinkPHP強大太多,完備性高出不少,Drupal更能應對複雜的業務邏輯
2、真正的大道至簡,Drupal全局只有一個入口文件,不管是多應用,還是單應用的前後台等,都只有一個入口,雖然使用者可以設定多個,但並不建議多個,這減少複雜性保持簡單,且為URL別名系統打下基礎,而ThinkPHP有複雜的多入口機制,在多應用時尤其如此,這也對URL別名的支援會較困難
3、Drupal在初始狀態下將類別載入器傳遞到處理核心中,這就天然支援替換或修改類別載入器,而ThinkPHP不支持,它只是載入而已,當需要修改類別載入器時,無法獲取,這一點導致靈活性大打折扣,例如很多類別不能替換為使用者自己的,例如你要替換「\think\Http」類別就比較麻煩。
多應用:
兩者都支援多應用,即多個系統復用同一套程式碼,但具體做法上Drupal要簡潔的多
面向介面程式設計:
在ThinkPHP的許多實作中,對類別沒有提取出接口,甚至有些重要類別也沒有接口,例如:
\ think\App
\think\Request
它們是如此核心和重要,但都沒有自己的獨立接口,ThinkPHP不是嚴格按照接口編程的,在靈活性上大打折扣,例如我想實作一個自己的app類去替換\think\App就做不到了,只能去修改核心,這樣每次升級是個問題,而在Drupal中是嚴格按照接口的,架構上完全面向接口,參數類型約束全部是接口,我們可以替換核心提供的任何類,而不必修改核心,包括最為重要的HTTP核心類:DrupalKernel,該類類似ThinkPHP的app類。
不嚴格按照介面編程除影響擴展性外,還有諸多其他壞處,比如對IDE不友好,文檔提取自動化難,代碼註釋無繼承,協作討論不方便等等
路由系統:
引用ThinkPHP官方教學的一句原文:
「ThinkPHP並非強制使用路由,如果沒有定義路由,可以直接使用「控制器/操作」的方式存取」
可見框架作者對路由的本質認識不足,如前文所述尚未抽像出數字1來,所說的「控制器/操作」的方式也應屬於預設路由或者內部路徑路由,而不是不用路由,看似無傷大雅的一點其實很重要,涉及本質認知,進而導致行為很不一樣。
路由是進入系統後的分岔路口,必定存在,許多業務邏輯都需要在這裡處理,例如權限控制、參數轉換、路徑別名處理、語言處理等等,在ThinkPHP中認為可以沒有路由,這導致了另外,這樣的認知結果勢必將事情變的鬆散和複雜,例如程式碼冗餘、使用不統一等。
而入口處理只是路由的兩大功能之一,另一個主要功能是出口處理,也就是全系統URL的生成,這對URL別名處理、語言協商、SEO等至關重要,但ThinkPHP中只有簡單的實現,尚未充分認識到路由系統的該責任,例如這裡提出一個需求:
#用戶在一個自定義函數中給全系統的URL加上“target="_blank"”怎麼實現?
容器與依賴注入:
此概念與叫法起源於Symfony框架,詳見:
https://symfony.com/ doc/current/components/dependency_injection.html
簡而言之其主要思想是在系統中設定一個中央大對象,也可以叫做母對象,其負責收集、保存、自動實例化我們常用的對象,在Symfony中,這個大對象稱為容器,其中保存的對象稱為服務,服務的定義可以採用YAML靜態提供或服務提供器方式動態提供,“定義”具備一定的格式,當我們需要某服務時,容器對象會依據定義去實例化服務對象,然後保存並返回,定義中涉及類別、參數、工廠方法、實例化後回調、配置器、公私有屬性、特徵繼承、延遲實例化等概念,容器形成前還會有服務編譯過程,以便處理服務組群、參數修改等高級功能,在容器中每一個服務都有一個ID,稱為服務ID,在使用之處透過該ID取得服務對象,容器中除了保存服務外還保存容器參數、服務別名等。
ThinkPHP的容器概念有Symfony的影子,但還非常幼小和初級,其實現離大道至簡相去甚遠,較混亂,比如沒有明確的服務ID概念,在Symfony容器裡的服務對象,必有對應的服務ID,而ThinkPHP將類似概念稱為abstract,其可以是標識符或類名,但部分容器方法又將其視為類名使用,例如:
\think\ App::register
\think\App::getService
看起來作者是想盡可能靈活,但卻導致了由不統一引發的混亂,在ThinkPHP中「服務」概念有單獨的定義(有點像操作系統的服務),但本質上還是Symfony服務,只是進行了特殊處理,在Symfony中將服務放到容器裡面叫做對服務進行“收集”,或者叫“注入”到容器,而ThinkPHP稱為將服務「綁定」到容器,顧名思義容器就是用來裝東西的,為什麼要叫綁定呢?這種叫法非常拗口,還有很多名字也詞不達意,例如運行容器中物件的實例化後操作,ThinkPHP稱為「執行後」操作,而不叫「實例化後」操作,計算機界有句名言:“什麼難?快取和命名”,在這一塊上ThinkPHP需要改進,現在的一些命名對新手不友好。
另外服務(在ThinkPHP中應該稱為綁定到容器中的類別、物件或回調才對)又可以向容器綁定服務這個特性看起來靈活,但是對程式碼追蹤和調試非常不友好,增加新人接手系統的難度,而Drupal得益於模組化設計,使得可以做到集中聲明(因為模組必定知道服務會依賴哪些服務,透過容器編譯機制也可以判斷某服務是否存在),這樣在追蹤程式碼和偵錯時就做到了盡可能簡單,匯出運行時容器中的服務定義也很方便,不用真的去實例化每個服務。
門面Façade:
這只是ThinkPHP中的概念,用來以靜態方式呼叫被包裝類別的動態方法,即用靜態方式代理類別到方法級別,這只是形式上的調整,內部依然需要實例化對象,其實該概念並沒有存在的必要,不但對IDE十分不友好還違背了PHP靜態方法設計初衷,只是彌補了ThinkPHP中容器功能的不足,在Drupal中無此概念,其功能目的是統一採用\Drupal::service($id)靜態方法獲取服務實例,進而由開發者自行調用其動態方法,如需不同實例則自行克隆,這也避免了use引入代理類別的麻煩。
助理函數
ThinkPHP中有個助手函數的概念,文件提到其目的是享受IDE自動提醒的便利,這相當於Drupal中的「\ Drupal」全域類別提供的靜態方法,或快速函數,但Drupal並不是因為IDE,而是更方便的取得服務,因為PHP函數或靜態類別方法是超全域可用的。
控制器與模型:
在ThinkPHP中認為控制器是用來做業務處理前邏輯的,必須是一個php類別或閉包,業務邏輯是「模式器」的事情,其實這是很僵化教條的一點,首先控制器可以是任何形式表示的php回調,包括函數、容器實例的方法(用容器ID進行定義)等,其次現實中業務邏輯的邊界並沒有那麼清晰,很難抽像出「模式」然後還能給出這個名字,再次控制器應該已經是業務處理的開始,而ThinkPHP概念中的控制器所做的事情應該是在路由中處理,這一點ThinkPHP已經意識到了,並在文檔中一筆帶過。
多語言處理:
在實作上ThinkPHP和Drupal都是基於英文作為開發元語言,ThinkPHP的翻譯實作非常簡陋,在現實中通常無法滿足需求,開發國際化應用時尤其如此(這應是應用範圍覆蓋不足導致的),Drupal具備完整的多語言系統,已經完整處理以下概念:
語言單複數問題(部分語言還不止單複數)上下文問題(「may」翻譯成「可以」還是「五月」呢?)JS裡面文字的翻譯介面、設定和內容語言的翻譯團隊翻譯協作機制向左文字語種的處理等等
而這些ThinkPHP都不具備,僅簡單的實作了模板裡面文字的翻譯,語句中變數的替換;此外Drupal天然具備多種語言協商機制,如使用者設定、URL前綴、會話資訊、網域名稱、HTTP頭、用戶代理標識等等,支援透過插件自訂語言協商機制,在ThinkPHP中預設僅支援URL、HTTP頭變數、cookie、瀏覽器,注意如果你以Cookie來傳遞語言訊息,在開發國際系統時可能會遇到法律問題,許多國家要求系統明確提問使用者是否能夠使用其Cookie;綜上使用ThinkPHP時需要開發者自行解決大多數語言問題,但實際上多語言系統貫穿整個系統,非常龐大複雜,Drupal由於是國際共建的系統,多語言是其一大亮點,是天然的多語言系統,只此一項就可能難住ThinkPHP開發者。
快取系統:
完整的快取系統有三個要素:逾期時間、失效標籤、上下文,Drupal對其有完整實現,而ThinkPHP只實現了時間和標籤,沒有實作上下文,何為上下文?簡單的說它指示同一個緩存鍵KEY下,被緩存物屬於誰在何種環境條件下進行的緩存,例如用戶的權限、登入狀態、語言、ip、協定版本、主題資訊等都屬於快取上下文,同一個KEY在不同上下文條件下需要讀取不同的快取物,這對大型系統設計至關重要,且該系統非常龐大,ThinkPHP需要開發者自行解決快取上下文的問題,此外ThinkPHP未提供快取合併機制,這將無法實現緩存的分層分級處理,要實現高效緩存,該功能是必不可少的。
會話Session:
使用ThinkPHP的開發者得自己解決會話相關問題了,為什麼呢? IT發展到今天,僅小微系統只使用一台伺服器,大多數系統都會負載均衡到多台伺服器上,因此應用必須要求無狀態,那麼會話資料就不能儲存在本機,通常的解決方案是存儲到資料庫中,基於此,由於ThinkPHP是一個框架無法提供資料庫儲存會話的現存方案,因此需要開發者自行處理,而Drupal本身已經考慮到負載均衡、應用無狀態等事情,會話預設已經儲存到資料庫,可以開箱即用,儘管ThinkPHP提供了擴展能力,開發者還是要付出許多人力成本去實現開發
在ThinkPHP的會話實現中有個問題:會話的保存不在腳本結束之後進行,而是在腳本裡面執行,這樣當使用者呼叫die或exit就會導致無法儲存,應當註冊關機函數才對,詳見php函數:
register_shutdown_function
#資料庫:
ThinkPHP和Drupal都支援多資料庫,該特性在ThinkPHP中自創了一個「分散式資料庫」的概念來描述,Drupal沒有專門渲染概念,只用業務標識對不同資料庫進行區分,二者也都支援主從配置和讀寫分離;但在實作上很明顯Drupal優雅很多,例如在資料庫配置的資料結構上,Drupal採用多維數組,第一級鍵名是業務標識,第二級鍵名是主從標識,其值就是連接配置信息,這樣的結構十分簡單,如果你要實現一個數據庫負載調度子系統,那麼該結構的接口是非常簡單的,而ThinkPHP的配置數據結構中,把所有的主機位址儲存在一個數組鍵下,把所有的密碼儲存在另外一個數組鍵下,等等諸如此類的還有用戶名等,這樣的結構在生成連接信息時還需要再次解析配置信息,不但閱讀修改不直覺也消耗了系統效能,資料庫負載調度子系統的介面也較複雜,非常不優雅。
二者也都支持多類型資料庫,Drupal核心自帶對mysql、pgsql、sqlite三種資料庫的支持,加上社群模組幾乎完整實現了對所有常用資料庫的支持,在底層,Drupal將不同資料庫的差異稱為“方言”,不同方言的處理在驅動層完成,向上層提供統一接口,換句話說上層資料庫操作類別感知不到底層用的是什麼資料庫,採用標準的SQL規範,這樣就完美屏蔽差異,實作了資料庫解耦,模組開發者就不用去考慮使用者用的是什麼資料庫,建表、查詢、修改等等全部是統一的,在應用層切換不同種類資料庫時可以做到一鍵搞定。
關於資料庫操作,Drupal由於是一個完整系統,已經預設實現了一整套非常先進的資料儲存結構,該結構提供了對系統資料層的支持,當所有人都基於統一資料結構時,奇妙的事情就產生了,分佈在全球的人們可以合作實現豐富的上層應用,該結構造就了大名鼎鼎的實體概念,由此Drupal也提供了更多關於數據的操作,比如實體查詢,用戶實現了開箱即用, Drupal是包容的,使用者也可以定義自己的資料結構。
對資料層的支援ThinkPHP是無法做到的,ThinkPHP用模型來處理資料封裝和操作,模型和實體相比,是非常初期和幼小的概念,它能做的實體皆可做,反過來則不行,例如模型不支援輸入用的欄位控制項、輸出用的格式化器、表單和檢視的顯示控制等等,究其原因,是因為這些都需要更高層次的實作。
中外開源生態與連結:
#在充分對比後,會明白ThinkPHP能做的Drupal都能做,做的更好,反過來卻不行,因為Drupal是一個完整後端系統,被人譽稱為WEB作業系統,已幫助做了更多的事情,常用需求基本上都有了,開箱即用,ThinkPHP開發者想要那些功能,則需要在ThinkPHP基礎上走非常遠的路,先不提品質問題,單就時間消耗就是一個驚人的數字(比如Drupal 8正式版發布之前,其各種開發版,就由一千多名國際頂尖開發者為此工作了五年),事實上許多Drupal開發者確實也不屑於去學習ThinkPHP或其他框架,但在國內可以發現一個很奇特的現象:為什麼國內還有很多小公司在用ThinkPHP? (關於這一點,可以到各招募平台搜尋PHP招募資訊就可略知一二),要解釋這一點有兩方面原因:
文化交流受阻:
中外文化、生活等的交流依然僅限於一小部分人,大部分人是沒有異國朋友的,主要原因是眾所周知的網路屏障和語言問題,語言不通應該是主要原因,我國發展太快,目前國內開發者主力是70後到90後這一批人,絕大部分英語溝通水平欠佳,啞巴英語,或者閱讀困難,他們往往本能的不會去接觸英文資料,00後或者10後的英語程度則高很多(得益於教授早,網路等),在未來他們會更多融入國際環境,所幸的是現在科技發達,翻譯軟體水準越來越高,也越來越多人投身到技術引進上面來,例如Drupal在中國就有「Drupal中國」、「愛碼文件匯」、「水滴間」、「Drupal大學」、「Think in Drupal」、「寧皓網」等等一大批科技平台,這些平台或部落格提供了巨量、幾乎完整的中文文檔,掃平了語言障礙。在北上廣深、成都、南寧、寧波等城市均有以Drupal為核心技術的開發公司。
壓力下導致的速食現象:
中國人絕對是世界上最勤奮的人群之一,這種勤勞很大程度上和壓力相關,住房、結婚、醫療、教育、養老每一個都是一座大山,「搞錢」必須是頭等重要的大事,對大多數普通民眾來說,保持匠心做長線積累風險太大,缺乏安全感,眼下能搞的錢先搞了再說,社會發展那麼快誰能知道以後什麼樣子,這種現象對我國基礎科學領域傷害巨大,同樣的在快速發展的IT業更是如此,我國開發者身上的擔子太重了,996甚至被大公司推崇,長期做著CURD這樣簡單的碼農的工作,很多開發者根本沒有太多時間去學習,稍有時間得用來陪陪家人、孩子、女朋友,自己休息的時間很少,學習深究就更難了,如果有多餘時間通常用來接私活搞外快,在這樣的大環境下,大家習慣於“吃快餐”,有鋤頭用就先用著,學習挖掘機沒有空,發展挖掘機更是成本高昂,最終導致了我國開源事業難以發展,為數不多的開源專案帶著濃濃的商業味,其中小公司靠廣告補貼,靠開源專案引流商業專案獲利(看看ThinkPHP的首頁就能感受到),大公司則出於培養後備人才、免費消除Bug等等而選擇開源,帶著濃厚的「勢力範圍」色彩,總的來說純粹的熱愛和興趣佔比很小,但這不應責備中國的開發者們,這是重壓力的大環境所致,現在也出現了逃離一線城市的現象,許多人去到不那麼繁忙,有些閒暇時間的二線城市,也許他們是開源的一種力量,得到APP(羅輯思維)也預測中國的創新中心可能會移動到那些擁有閒暇的二線城市。
相反國際開源的土壤好的多,由許多已開發國家主導,而這些國家通常是福利型國家,相比壓力不大,人們靠興趣做事的空間很大,許多參與開源的人首要考慮的是人生意義,關於此有個“馬斯洛需求模型”讀者可以了解下,“喜歡”保證了“質量”,福利可以讓開發者不考慮年齡、工作,在一年一度的DrupalCon大會上,你可以看到很多開發者年齡都非常大,五六十歲的人很多,他們在一起眼中帶光的談論技術,將一生的積累注入到Drupal中。
當然國際開源也並非主要由已開發國家參與,英語系的不發達國家也是重點參與者,他們往往是透過開源衍生的商業計畫賺取外匯,典型國家就是印度,在印度兩極化嚴重,曾經被英國殖民過,在其高端人群中英語普及率很高,這一點讓印度高度融入國際開源,相應的造就了印度較高的軟體開發實力。
開發者職業規劃:
這一節討論下國內開發者的職業規劃問題,在國內社會一直有一種聲音: “程式設計師是吃青春飯的”,對應的通常就是35歲門檻,你可能經常看到某某大公司辭退35歲的大齡開發者,一些公司招聘年齡要求不能超過35歲,很奇怪,35歲正是能力上累積較深,很多事情的分寸上拿捏得當的年紀,為什麼會出現這個現象呢?讓我們來探索下:
首先那些新聞有很重的博眼球嫌疑,就像「女司機」一樣,實際上女司機的事故率比男司機還少,正是因為少所以才是新聞,才能讓你瀏覽,但這樣的新聞多了你會形成錯覺,因此35歲門檻一定程度上被過度渲染了,造成了不好的影響,甚至有些人無理由跟風。
但35歲門檻又有一些道理,這要選擇性區分,如果開發者一直做著CURD這樣簡單、重複性的體力活(真正的碼農),那麼當達到35歲時,和剛出校門一兩年的年輕人比,競爭力可想而知,35歲時孩子上學、父母身體、住房等壓力會很大,逼迫開發者提出更高的待遇要求,家庭事務、應酬交際等也多,不願加班,通常工齡長累加的薪水相對較高,如果你做的事情年輕人也能做,老闆選誰呢?同時年紀大了多少有些面子問題,如果上司是個比自己小很多的年輕人,是否服管呢?對於年輕人來說管理一個比自己年長很多的人有時也挺尷尬。根據這些可見35歲門檻的存在有一定的道理。
時間不等任何人,那麼開發者如何避免35歲門檻,該如何規劃自己的人生呢?
如果你發現自己並不真的喜歡技術,那麼你應該在年紀上還有競爭力時趁早轉型,跟隨內心,找到喜歡的事情並開始積累競爭力。
如果你真的很喜歡技術,並願意且準備好以此度過一生,那麼你就需要高效積累,不停學習,時刻注意拉開和年輕人的技術差距,他們有壓力小和體力強的優勢,你需要以技術優勢來彌補,大神之路不是你可選可不選,而是必須選擇的,當到達35歲時,你必須是一個大神,擔起年輕人難以勝任的系統崗位。
這裡需要提醒你隨著社會的發展,技術的門檻其實是在逐步提高的,比如你可能聽說過“全端工程師”,但那隻屬於互聯網時代初期,現在社會分工太細太深,已經不存在全棧了,如果存在那可以換個叫法“樣樣懂,門門差”,因為人的精力差距不會太大,你選擇研究全部,別人選擇鑽研一處,而用人單位是按崗位用人的,你需要考慮誰更有優勢,理智會讓你選擇深鑽一門,週邊懂得即可,但這樣你會成為一個大機器上的一個部件,你的選擇自由被限制,細分門檻要求會很精專,淺嚐輒止,不求精深必面臨淘汰。
做這樣的機器部件不適合有創業理想的人,那麼創業會面臨些什麼呢?看看中國社會的發展,所有通用的IT需求你可能都沒有機會,例如網站被公眾號取代,不多的網站市場也被SaaS平台佔領,與這樣的平台競爭,他們只需要點滑鼠初始化即可,你得寫代碼,他們按時間收費可以很低,你得一次性收費,站在客戶角度首要考慮的當然是成本問題,通用需求還包括電商系統、直播系統、內容付費系統等等,而這些都有很成熟的現存解決方案,在規模優勢上,微盟、有讚、微擎、微積木等等這些都是已經發展起來的很不錯的SaaS平台,非通用的IT需求呢?會形成許多垂直領域的解決方案,山頭被搶佔瓜分,比如美團、滴滴、土巴兔、頂呱呱等等,他們所在的領域你都很難再有機會,留給開發者的僅剩下數量不多的真正需要客製化的需求,這樣的需求有個特點,由於是定制,成本原因決定了客單價必須高,此時客戶會對創業者公司的實力有所要求,你有多少員工?有多大的辦公室?有多長時間的歷史累積?有多少案例?註冊資本有多高?
此外IT發展到今天,同一個應用系統在軟體形式上會呈現多種形式,通常需要App、小程式、網頁等中的一種或幾種,也涉及跨平台(APP有安卓、IOS和即將出現的鴻蒙,小程式涉及微信、支付寶、百度、抖音等等),雖然有UNIAPP這樣的工具,但在客戶要求原生應用時仍然所需技能很多,這就導致必須組建團隊,團隊成員還包括非技術人員等,例如業務員、財務等,這些都形成了一定的進入門檻,最終你會發現創業需要的不止是技術更多的是資金。
說到這裡你是否覺得路很難?但請你相信不是只有IT領域是這樣的,有競爭的地方都會這樣,任何成功都不容易,唯有你的興趣能保證你能走多遠、走多高,所以請跟隨自己的內心。
如果你跟隨內心,深思後依然選擇了做技術,當一個了不起的大神,那麼你該怎麼做呢?首先你必須要注重積累,尤其是要站在巨人的肩膀上向著未開發的土地猛衝,你需要找到所在細分領域最有前景的生態圈,加入進去,回到PHP開發框架上來,小白看框架它只是進一步封裝提供了要的功能,而大神看框架是它提供了一個統一的協作平台,大家都在同一個平台上進行創造,這樣才能避免自己重複造輪子,在經濟成本上才足夠划算,借助眾人的力量才能騰出手來發展自己的事情。
基礎平台的統一性非常重要,只有這樣人類才能累積向前,才能降低成本,但統一平台的形成有個很有意思的規律,那就是最終只會剩一個作為主要平台,然後有個處於第二位的平台來形成競爭後備,第三第四位的基本可以忽略不計了,且第一位和第二位在體量上會選差很遠,這樣的列子有很多,比如歷史上有幾千個作業系統,最後剩下window和linux,二者用戶數選差很遠,又比如安卓和蘋果、淘寶和京東、抖音和快手、美團和餓了麼等等皆是如此,一旦格局形成,便很難撼動,例如微軟就撼不動安卓,不是因為技術,而是因為滾雪球效應在發揮作用,王者會更強、更大,敗者逐漸落寞消失,即便王者犯了些小錯發展也不可改變,例如現在我們使用的鍵盤,其字母排列其實不是最合理的,歷史上也出現過排布合理的鍵盤,但由於大家已經習慣於現在的鍵盤,所以也就延續使用了,要成為王者有兩點很重要:技術層面的先進性要足夠、社區生態要建立滾雪球效應,這兩點相輔相成。
那麼在PHP框架領域誰會成為這個統一的基礎平台呢?開源專案的主要發展力量應該是大批使用者在使用過程中不斷的提煉並總結,然後一起對其的持續討論並改進,而不是幾個人單憑自己的思考或經驗,因此如果在ThinkPHP和Symfony中做選擇,答案已經非常清楚,其實很早Symfony就意識到統一平台的意義所在,因此致力於解耦的、完備的基礎組件的建立,並反復迭代,以至於現存其他一些框架也用Symfony的組件,例如Laravel和ThinkPHP,Symfony一再強調“標準”,現在也已經存為php開發領域的事實標準,因為標準化就是統一平台的必備條件。
至於Drupal則是在Symfony基礎上建立起來的更高一層的統一標準平台,成為了完整系統的標準基礎,在這裡常用的應用層功能幾乎都已被提供,人們正在此在統一平台上,基於模組化設計,創造更多面向未來的功能,實現Drupal的理想「提供卓越的數位體驗」。
決策者技術選型:
如果你是創業老闆,或專案總監,正為專案進行技術選型,那麼這裡為你提供幾個注意事項:
控製成本:
這似乎不用多說,理所當然,但你真的控製成本了嗎?軟體是無形的,如果你不是專業人士,很難控製成本,這裡說一些坑:
在目前環境下,想做個長遠規劃的項目,能自己開發,就不要外包,有些東西看起來一樣實則差距非常大,不專業的人很難看出健壯性、擴展性、安全性、持續性等等性質在兩個系統間有何不同,比如同樣功能的系統,負載五千和負載五千萬的開發成本是完全不同的,又例如軟體文件工作量有時會遠高於軟體開發本身,文件是保障系統長遠發展的重點,但外包很難做到文件齊全,外包品質通常會讓你在日後買單,究其原因,不是因為外包公司實力不行,而是成本問題。
少欠技術債:
不要在開始因為省錢,找一些累積不夠的開發者,這裡分享個故事:有位老闆和技術總監在人才招募上出現了分歧,技術總監要求給出崗位薪資1.5萬,來了一個應徵者只要八千,技術總監不要,但老闆大喜,認為賺到了,為什麼要傻傻的多給錢呢?有時小白會在系統中留下巨大隱患,這位技術總監就是看到了技術債問題,開發團隊一定要有積累深的技術骨幹來把控系統,同時在選擇基礎系統時不要選擇成熟度低的東西,這樣保證盡可能不欠技術債,否則你會開始輕車熟路,後面深陷泥潭,如果遇到商業關鍵窗口期,那麼神仙也救不了你
借力加速:
社會發展到今天,其實很多IT系統功能都已經有了,而且非常齊全,你不需要自己去開發,比如要在ThinkPHP和Drupal之間選擇,我會毫不猶豫的選擇Drupal,因為ThinkPHP只是個半成品,通常在各種業務系統中有些功能是必須的,例如垃圾回收系統、狀態系統、鍵值儲存、批次系統、排程任務系統、資料類型化系統、Ajax系統、資料檢視引擎、版本支援系統、權限系統等等,這些在ThinkPHP都沒有,而Drupal很完備,而要在ThinkPHP上開發出這些,需要數月到數年,不僅談不上基礎統一平台的優勢,也很難保證自己開發的程式碼質量,不但白白浪費了資源,在後期新加成員還需要付出高昂的培訓費用,有現成的基礎齊全的、成熟的系統為什麼不用呢?
融入大環境:
開發系統要融入大環境,除了借力加速外,還在於後備人才的獲取,讓開發者和專案解耦,不要因為在現有開發者離職或不夠時,找不到足夠的開發者快速加入項目,融入大環境,解耦開發者很大程度上保障了項目的發展安全。
國家開源建議:
這一節我們站在國家層面,來看看應當如何對待開源,我國日漸強大,很多國人都期待著超越美國那一天早日到來,那麼中國要突破美國封鎖,達到超越的目的,就必須要參與國際開源成為貢獻主力,而不是自己搞一套獨立的體系(自建體系應發生在新生事物上,例如下一代物聯網作業系統鴻蒙),因為開源是全人類的開源,而不是哪一個國家的開源,閉門造車出門不合轍,會讓中國遠離世界,要知道中國只有十四億人,而全世界有七十多億人,生態力量無法和全世界對抗,因此理性的做法是參與開源,努力做出奉獻,一則繼承已有的人類發展成果,站在巨人基礎上發展更快,二則選擇和多數人在一起,開放國門,建立影響力,才有可能建立大國形象。
【相關教學推薦:thinkphp框架】
以上是drupal對比thinkphp,看國內的開源環境的詳細內容。更多資訊請關注PHP中文網其他相關文章!