PHP 框架實現原理

1、MVC模式php

MVC模式(Model-View-Controller)是軟件工程中的一種軟件架構模式。html

控制器(Controller)。負責轉發請求,對請求進行處理。前端

視圖(View)。界面設計人員進行圖形界面的設計。laravel

模型(Model)。程序員編寫程序應有的功能(實現算法等),數據庫專家進行數據管理和數據庫設計(能夠實現具體的功能)。即,數據和改變數據的操做。程序員

 可參考:https://laravelacademy.org/post/9614.html算法

 

2、框架結構數據庫

單一入口使得每個請求都需通過這個入口文件處理,文件由此開始進行分發,減小重複存在一些通用的初始化操做,更容易管理Controller層。後端

 

路由:數組

路由是對來自客戶端的請求的URL解析,並把指定的URL分派給對應的 Controller 來處理。安全

一個Controller控制器又是由一組具備相關功能的Action組成,Action方法是一個URL訪問的最小單元。

路由就是找到這個控制器文件,而且執行它下面的方法。

 

數據模型:

一、數據庫類的實現

二、數據模型層理論

對象關係映射(Object Relational Mapping,簡稱ORM、O/RM 或 O/R mapping)。

把數據庫中的一個表直接映射爲一個對象,基於這個對象進行賦值、保存等操做,而且減小寫SQL語句,提升開發效率。

PO(persistant object): 與一個數據庫中的表的一行記錄相對應的對象,稱之爲PO持久對象。PO中應該不包含任何對數據庫的操做(也就是隻有屬性,沒有方法),它僅僅是對錶記錄的映射。

BO(business Object): 主要做用是把業務邏輯封裝爲一個對象。這個對象能夠包括一個或者多個其餘對象。好比出貨單就包含有商品簡介、訂單詳情、消費者信息等。商品簡介對應一個PO,訂單詳情對應一個PO,消費者聯繫信息對應一個PO。創建一個對應出貨單的BO對象處理出貨單,每一個BO包含這些PO。這樣處理邏輯時,能夠針對BO去處理。

VO(Value Object,值對象): 界面顯示的數據對象,一個界面對應一個VO對象。

DTO(Data Transfer Object): 傳輸PO對象到VO進行一些過濾。它能夠用在任何須要數據傳輸的地方。

注意:在建立PO、DTO、VO時,不要給這些對象賦初始默認值。

傳統的ORM模式提倡數據和數據操做分離。而在Active Record中,模型層集成了ORM的功能,它們既表明實體,包含業務邏輯,又是數據對象,並負責把本身存儲到數據庫中,存儲的這一部分代碼是在父類中實現好的,屬於框架的一部分,模型只須要簡單調用父類的方法來完成持久化。在Active Record模式中的數據對象再也不是PO對象,而是DAO(Data Access Object)對象。

好比,User類繼承了父類Model,擁有父類父類所擁有的增刪改查等功能(好比調用save()方法,實現數據保存;但其內部仍是使用SQL拼裝實現數據庫操做,只是封裝好後使用ORM會自動生成SQL語句;通常用ORM實現簡單的CURD操做,複雜的查詢仍是更傾向於使用原生的SQL實現),進而User這個PO對象上升爲一個Dao對象。

Service:把一系列的數據庫操做組合起來,稱之爲Service。向上負責接收頁面傳遞的參數以及數據的傳輸,向下負責與數據庫打交道。

視圖:

早期,使用smarty等專業的模板引擎來作視圖層,後期,隨着先後端分離理念的發展以及前端MVC框架的誕生,愈來愈多涉及顯示的工做都由前端JavaScript +JSON來實現了。MVC中的顯示層開始輕量化、API化發展。

 

3、框架增強

一、命名空間

詳見:https://www.php.net/manual/zh/language.namespaces.basics.php

 

二、自動加載

composer自動加載一共支持4種自動加載方式:

PSR-0:因爲PHP5.3以後纔有的namespace這樣的高級屬性,因此低於此版本的,PSR組織用了一個僞namespace(經過命名的下劃線來映射目錄結構)的作法來模擬命名空間。

被結合爲一個單一的鍵值對數組,存儲至 autoload_namespaces.php 文件中。

PSR-4(推薦):轉換成namespace與文件目錄的MAP形式,並存在 autoload_psr4.php 文件中,能夠在此文件中找到真實路徑

class-map:支持自定義加載不遵循PSR-0/4規範的類庫。要配置它指向須要的目錄,以便可以準確搜索到類文件。會遍歷此目錄而後將裏面的類文件和路徑一一對應,存放在autoload_classmap.php 內。

直接包含file:能夠直接將文件包含進來。安裝後會存放在 autoload_files.php 文件中。

詳見: https://www.cnblogs.com/cshaptx4869/tag/Composer/

 

三、錯誤處理機制

set_error_handler()

set_exception_handler()

詳見:http://www.javashuo.com/article/p-cnrhshpm-e.html

 

四、控制反轉 IOC(inversion of control)與 依賴注入DI(dependency injection)

 控制反轉是面向對象開發中的一種設計思想。IOC意味着將你設計好的對象交給容器控制,而不是直接在你的對象內部控制。

如何理解?明確「誰控制誰,控制什麼,爲什麼是反轉,哪些方面反轉了」。

誰控制誰,控制什麼:傳統面向對象程序設計,咱們直接在對象內部經過new進行建立對象,是程序主動去建立以來對象;而IOC是有專門一個容器來建立這些對象,即由IOC容器來控制對象的建立;因此,是IOC容器控制對象,主要控制了外部資源獲取(不僅是對象建立,還包括好比文件等)。

爲什麼是反轉,哪些方面反轉了:傳統下是本身在對象中主動控制去直接獲取依賴對象;反轉則是由容器來幫忙建立及注入依賴對象,因爲容器幫咱們查找及注入依賴對象,對象只是被動接受依賴對象,因此是反轉;總結一下就是,之前是由應用程序控制資源建立,如今控制權轉移到了IOC容器,因此叫控制反轉。

爲何這麼作,這麼作的意義何在?

依賴注入,是組件之間依賴關係由容器在運行期決定。即由容器動態地將某個依賴關係注入到組件之中。依賴注入的目的並不是是爲軟件系統帶來更多功能,而是爲了調高組件重用的效率,併爲系統搭建一個靈活、可擴展的平臺。經過依賴注入機制,咱們只要經過簡單的配置,而無需任何代碼就可指定目標須要的資源,完成自身的業務邏輯,而不須要關係具體的資源來自何處,由誰實現。依賴注入下降了建立對象的成本,使得對象之間鬆耦合。

DI的關鍵是「誰依賴誰,爲何須要依賴,誰注入誰,注入了什麼」。

爲何須要依賴:應用程序須要IOC容器來提供對象須要的外部資源。

誰注入誰:IOC容器注入應用程序某個對象,應用程序依賴的對象。

注入了什麼:注入某個對象所須要的外部資源(包括對象、資源、常量數據)。

DI和IOC是相輔相成的概念,IOC的實現是使用了DI,而DI的目的就是爲了實現IOC。

依賴注入DI和控制反轉IOC是對同一件事情的不一樣描述,它們描述的角度不一樣。依賴注入是從應用程序的角度在描述,應用程序依賴容器建立並注入它所須要的外部資源。而控制反轉是從容器的角度在描述,容器控制應用程序,由容器反向的嚮應用程序注入應用程序所須要的外部資源。

IOC會使用最合適的策略來管理對象,須要使用單例的地方,容器就始終只提供一個對象。須要使用多例的時候,容器就每次幫咱們建立一個新對象(固然也能夠手動告訴容器怎麼作)。

實際上IOC容器自己也就是個大對象,在整個生命週期裏保證只有一份。能夠保存在Session中,也能夠保存在內存中。

 

五、攔截器和插件

攔截器能夠用來做爲權限控制、處理輸入和輸出等場景。

全部的攔截器組成一個攔截棧,按照從上到下進入,而後從下到上退出的順序進行調用。

具體實現:能夠定義一個攔截器接口InterceptorInterface,子類去實現,而後在配置中正則定義哪些請求須要使用(如定義數組)。

整個流程是,全部請求會按照配置中的攔截器棧,從上到下走一遍,激活攔截器前置preHandle方法,而後激活控制器自帶的_bofore_方法(若是有的話),再激活當前須要執行的Action,緊接着是控制器再帶的_after_方法(有的話),而後從上到下方向激活攔截器的postHandle方法。

實現插件也是同理,定義一組插件接口,而後用戶本身擴展這個接口。框架只須要啓動時自動讀取全部實現了Plugin接口的類,並初始化注入框架的上下文環境便可。

 

六、Request加強和安全防護

 XSS、CSRF、SQL注入等過濾

避免跨站請求僞造攻擊的措施就是對寫入操做採用非 GET 方式請求,同時在請求數據中添加校驗 Token 字段,Laravel 也是這麼作的

詳見:https://laravelacademy.org/post/4610.html

相關文章
相關標籤/搜索