摘要:在這個(gè)后面執(zhí)行用戶自定義的,這些是在定義回調(diào)函數(shù)的時(shí)候一起給定當(dāng)前需要調(diào)用的列表。而傳統(tǒng)的以正則表達(dá)式做映射方式,查找回調(diào)函數(shù)時(shí)間不穩(wěn)定,最壞情況需要執(zhí)行一遍所有的正則表達(dá)式。
之前使用dispatch, 但是從4.0到現(xiàn)在的8.0 API變動(dòng)比較大,特別是在最近兩次大的版本的升級(jí),為了保持代碼簡(jiǎn)潔丟失了向下兼容的特性。
感覺作者的的核心思想不是很堅(jiān)定。所以生出了自己造輪子的沖動(dòng)。
router.lua這個(gè)是一個(gè)微型的可以在openresty里面運(yùn)行的路由控制器,曾經(jīng)幫作者做了一次重大改版,現(xiàn)在還是這個(gè)項(xiàng)目第二貢獻(xiàn)者。
其中的思想是很值得借鑒的:
使用樹形結(jié)構(gòu)來保存url和handler的映射關(guān)系。(按照樹形結(jié)構(gòu)查找保證了查找回調(diào)函數(shù)的效率Olog(n),而傳統(tǒng)的以正則表達(dá)式做key映射handler方式,查找回調(diào)函數(shù)時(shí)間不穩(wěn)定,最壞情況需要執(zhí)行一遍所有的正則表達(dá)式)
將reqest method定義成是match函數(shù)的一個(gè)封裝形式。便于提供方便的形式來映射路由。
Router鑒于以上兩個(gè)非常好的特性,所以就把這個(gè)lua的庫在PHP下面重寫了一遍。同時(shí)在寫的過程中加入了一些新的特性:
增加error這個(gè)API,一個(gè)API提供兩種調(diào)用方式(這個(gè)借鑒了dispatch里面的一些特性,有點(diǎn)像jquery的某些方法),可以兼具定義error handler和觸發(fā)error handler的作用。
增加hook API,同樣有兩種調(diào)用方式。
默認(rèn)觸發(fā)“before”和“after”兩個(gè)hook。分別在執(zhí)行真正的handler前后。
在“before”這個(gè)hook后面執(zhí)行用戶自定義的hook,這些hook是在定義回調(diào)函數(shù)的時(shí)候一起給定當(dāng)前url需要調(diào)用的hook列表。(當(dāng)然這些hook全部都要用戶自己定義回調(diào)函數(shù))
安裝這個(gè)微型的路由控制器已經(jīng)提交到packagist網(wǎng)站,可以通過composer工具安裝
composer require lloydzhou/router此處附README里面的一個(gè)例子:
(new Router()) /* 定義錯(cuò)誤處理函數(shù) */ ->error(401, function($message){ header("Location: /login", true, 302); die($message); }) ->error(405, function($message){ header("Location: /hello/world", true, 302); }) ->error(406, function($message){ die($message); }) /* 定義hook函數(shù),除了內(nèi)置默認(rèn)調(diào)用的before和after,還定義了檢查登錄的auth */ ->hook("auth", function($params){ if ("lloyd" == $params["name"]) return $params; $params["router"]->error(401, "Forbiden"); }) /* 定義after這個(gè)鉤子函數(shù),支持json或者jsonp格式輸出 */ ->hook("after", function($result, $router){ if ($result) { header("Content-type: application/". ($_GET["jsoncallback"]?"javascript":"json")); if ($_GET["jsoncallback"]) print $_GET["jsoncallback"]. "(". json_encode($result). ")"; else print json_encode($result); } }) ->hook("before", function($params){ //$params["name"] = "lloydzhou"; return $params; }) /* 定義url映射 */ ->get("/", function(){ echo "Hello world !!!"; }) ->get("/hello/:name", function($name){ echo "Hello $name !!!"; }) ->get("/hello/:name/again", function($name){ echo "Hello $name again !!!"; }, "auth") ->get("/hello/:name.:ext", function($name, $ext){ if ("js" == $ext || "json" == $ext) return array("name"=>$name); return array("code"=>1, "msg"=>"error message..."); }, "auth") /* 程序入口,以當(dāng)前的url查找對(duì)應(yīng)的處理函數(shù),并獲取變量執(zhí)行該函數(shù) */ ->execute();啟動(dòng)服務(wù)
php -S 0.0.0.0:8888 test.php測(cè)試
curl -vvv 127.0.0.1:8888/hello/ url未能映射成功,觸發(fā)405錯(cuò)誤處理函數(shù), 自動(dòng)跳轉(zhuǎn)向 URL: "/hello/world" curl -vvv 127.0.0.1:8888/hello/lloyd 返回 "Hello lloyd !!!" curl -vvv 127.0.0.1:8888/hello/lloyd/again 返回 "Hello lloyd again !!!" curl -vvv 127.0.0.1:8888/hello/world/again 在鉤子函數(shù)auth處理失敗觸發(fā)401錯(cuò)誤處理函數(shù), 自動(dòng)跳轉(zhuǎn)到 URL: "/login" curl -vvv 127.0.0.1:8888/hello/lloyd.json 支持“/”和“.”作為pathinfo的分隔符,并且和after鉤子函數(shù)配合,返回json格式文本 {"name": "lloyd"} curl -vvv 127.0.0.1:8888/hello/lloyd.js?jsoncallback=test 返回jsonp格式文本 test({"name": "lloyd"}) curl -vvv 127.0.0.1:8888/hello/lloyd.jsx?jsoncallback=test 最后的后綴名不匹配,輸出錯(cuò)誤jsonp格式的消息 test({"code":1,"msg":"error message..."})編譯
開發(fā)環(huán)境使用CRouter替代Router可以自動(dòng)檢測(cè)文件修改時(shí)間,并且編譯成原生數(shù)組保存至router.inc.php
(new CRouter("router.inc.php", true))
發(fā)布的時(shí)候只需要把路由映射的部分替換成以下兩行代碼即可跳過創(chuàng)建路由映射表的階段。以節(jié)省時(shí)間!??!
$router = include("router.inc.php"); $router->execute();性能
使用樹形結(jié)構(gòu)來保存url和handler的映射關(guān)系。查找URL映射函數(shù)的時(shí)候保證了查找回調(diào)函數(shù)的效率O(log n)。
而傳統(tǒng)的以正則表達(dá)式做key映射handler方式,查找回調(diào)函數(shù)時(shí)間不穩(wěn)定,最壞情況需要執(zhí)行一遍所有的正則表達(dá)式。
支持編譯,將映射好的樹形路由映射數(shù)組直接編譯成源碼。不需要每次PHP請(qǐng)求的時(shí)候重新切割pathinfo再來生成樹形節(jié)點(diǎn)。以節(jié)省時(shí)間!
DEMO為了一邊測(cè)試,一邊完善這個(gè)庫。所以使用這個(gè)庫結(jié)合另外一個(gè)ActiveRecord和MicroTpl 寫了一個(gè)簡(jiǎn)單的博客,里面基本涵蓋了這幾個(gè)庫的API。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/21150.html
摘要:每一個(gè)開發(fā)者都知道,擁有一個(gè)強(qiáng)大的框架可以讓開發(fā)工作變得更加快捷安全和有效。官方網(wǎng)站是一款老牌的框架,現(xiàn)在穩(wěn)定版本已經(jīng)是了。官方網(wǎng)站是由最大的社區(qū)之一的管理開發(fā)的,也是一個(gè)開源的框架。 對(duì)于Web開發(fā)者來說,PHP是一款非常強(qiáng)大而又受歡迎的編程語言。世界上很多頂級(jí)的網(wǎng)站都是基于PHP開發(fā)的。 每一個(gè)開發(fā)者都知道,擁有一個(gè)強(qiáng)大的框架可以讓開發(fā)工作變得更加快捷、安全和有效。在開發(fā)項(xiàng)目之前選...
摘要:路由控制器性能測(cè)試前言前段時(shí)間抽空寫了個(gè)微型路由控制器可以在我的另一篇文章里面看到詳細(xì)的介紹。上門有測(cè)試以及這幾個(gè)路由控制器的性能,總體來說和在最壞的情況下表現(xiàn)最好。同樣的測(cè)試條件。所以本次測(cè)試僅僅針對(duì),以及。 PHP路由控制器性能測(cè)試 前言 前段時(shí)間抽空寫了個(gè)微型路由控制器可以在我的另一篇文章里面看到詳細(xì)的介紹。雖然在設(shè)計(jì)的時(shí)候及盡量避開了正則匹配和數(shù)組循環(huán)這種耗時(shí)的操作。盡量節(jié)省時(shí)...
摘要:所以,是幫助您創(chuàng)建您的項(xiàng)目的測(cè)試框架,單元測(cè)試。行為驅(qū)動(dòng)開發(fā)是一個(gè)來自測(cè)試驅(qū)動(dòng)開發(fā)的開發(fā)過程。這種語言被稱為,是用來描述被測(cè)試的預(yù)期的行為。代碼將被測(cè)試并且沒有異常。這些標(biāo)準(zhǔn)提出了現(xiàn)代編碼風(fēng)格。 本文來自medium----原文鏈接; 歡迎作客我們的php&Laravel學(xué)習(xí)群:109256050 你需要開始使用測(cè)試 這是我每天對(duì)自己說的話。像很多人一樣,我不會(huì)像TDD所建議的那樣測(cè)試...
摘要:這些所有的結(jié)構(gòu)都只是該微型框架的一個(gè)基本結(jié)構(gòu),實(shí)際上復(fù)雜的框架會(huì)有很多擴(kuò)展的函數(shù)以及外部插件,可以在這個(gè)目錄結(jié)構(gòu)上做出相應(yīng)調(diào)整。 一、框架整體分析在實(shí)現(xiàn)一個(gè)框架之前,我們需要了解這個(gè)框架應(yīng)該達(dá)到一個(gè)怎樣的效果,按照傳統(tǒng)框架的思路,大致可以總結(jié)出以下這么幾條:1.實(shí)現(xiàn)MVC架構(gòu),將控制、邏輯、視圖層進(jìn)行分離。2.封裝各種函數(shù)及功能模塊,實(shí)現(xiàn)一處編寫,多處調(diào)用,減少代碼冗余。3.便于擴(kuò)展,...
摘要:新聞焦點(diǎn)英特爾凌動(dòng)處理器產(chǎn)品家族是首款基于微架構(gòu)的處理器,擁有種可定制化配置,面向微型服務(wù)器入門級(jí)網(wǎng)絡(luò)和冷數(shù)據(jù)存儲(chǔ)。全球領(lǐng)先的托管服務(wù)公司與已經(jīng)對(duì)英特爾凌動(dòng)片上系統(tǒng)進(jìn)行了測(cè)試,并計(jì)劃于下一季度在其入門級(jí)專用托管服務(wù)中部署該產(chǎn)品。 新聞焦點(diǎn) · 英特爾凌動(dòng) C2000 處理器產(chǎn)品家族是首款基于 Silvermont 微架構(gòu)的處理器,擁有13 種可定制化配置,面向微型服務(wù)器、入門級(jí)網(wǎng)絡(luò)...
閱讀 3194·2020-01-08 12:17
閱讀 2050·2019-08-30 15:54
閱讀 1208·2019-08-30 15:52
閱讀 2101·2019-08-29 17:18
閱讀 1092·2019-08-29 15:34
閱讀 2517·2019-08-27 10:58
閱讀 1929·2019-08-26 12:24
閱讀 437·2019-08-23 18:23