资讯专栏INFORMATION COLUMN

一个PHP的微型路由控制器

rollback / 3147人阅读

摘要:在这个后面执行用户自定义的,这些是在定义回调函数的时候一起给定当前需要调用的列表。而传统的以正则表达式做映射方式,查找回调函数时间不稳定,最坏情况需要执行一遍所有的正则表达式。

之前使用dispatch, 但是从4.0到现在的8.0 API变动比较大,特别是在最近两次大的版本的升级,为了保持代码简洁丢失了向下兼容的特性。

感觉作者的的核心思想不是很坚定。所以生出了自己造轮子的冲动。

router.lua

这个是一个微型的可以在openresty里面运行的路由控制器,曾经帮作者做了一次重大改版,现在还是这个项目第二贡献者。

其中的思想是很值得借鉴的:

使用树形结构来保存url和handler的映射关系。(按照树形结构查找保证了查找回调函数的效率Olog(n),而传统的以正则表达式做key映射handler方式,查找回调函数时间不稳定,最坏情况需要执行一遍所有的正则表达式)

将reqest method定义成是match函数的一个封装形式。便于提供方便的形式来映射路由。

Router

鉴于以上两个非常好的特性,所以就把这个lua的库在PHP下面重写了一遍。同时在写的过程中加入了一些新的特性:

增加error这个API,一个API提供两种调用方式(这个借鉴了dispatch里面的一些特性,有点像jquery的某些方法),可以兼具定义error handler和触发error handler的作用。

增加hook API,同样有两种调用方式。

默认触发“before”和“after”两个hook。分别在执行真正的handler前后。

在“before”这个hook后面执行用户自定义的hook,这些hook是在定义回调函数的时候一起给定当前url需要调用的hook列表。(当然这些hook全部都要用户自己定义回调函数)

安装

这个微型的路由控制器已经提交到packagist网站,可以通过composer工具安装

composer require lloydzhou/router
此处附README里面的一个例子:
(new Router())
/* 定义错误处理函数 */
->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函数,除了内置默认调用的before和after,还定义了检查登录的auth */
->hook("auth", function($params){
    if ("lloyd" == $params["name"])
    return $params;
    $params["router"]->error(401, "Forbiden");
})
/* 定义after这个钩子函数,支持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")
/* 程序入口,以当前的url查找对应的处理函数,并获取变量执行该函数 */
->execute();
启动服务
php -S 0.0.0.0:8888 test.php
测试
curl -vvv 127.0.0.1:8888/hello/
url未能映射成功,触发405错误处理函数, 自动跳转向 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 
在钩子函数auth处理失败触发401错误处理函数, 自动跳转到 URL: "/login"

curl -vvv 127.0.0.1:8888/hello/lloyd.json 
支持“/”和“.”作为pathinfo的分隔符,并且和after钩子函数配合,返回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
最后的后缀名不匹配,输出错误jsonp格式的消息 test({"code":1,"msg":"error message..."})
编译

开发环境使用CRouter替代Router可以自动检测文件修改时间,并且编译成原生数组保存至router.inc.php

(new CRouter("router.inc.php", true))

发布的时候只需要把路由映射的部分替换成以下两行代码即可跳过创建路由映射表的阶段。以节省时间!!!

$router = include("router.inc.php");
$router->execute();
性能

使用树形结构来保存url和handler的映射关系。查找URL映射函数的时候保证了查找回调函数的效率O(log n)。

而传统的以正则表达式做key映射handler方式,查找回调函数时间不稳定,最坏情况需要执行一遍所有的正则表达式。

支持编译,将映射好的树形路由映射数组直接编译成源码。不需要每次PHP请求的时候重新切割pathinfo再来生成树形节点。以节省时间!

DEMO

为了一边测试,一边完善这个库。所以使用这个库结合另外一个ActiveRecord和MicroTpl 写了一个简单的博客,里面基本涵盖了这几个库的API。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/21150.html

相关文章

  • 你不可不知道20个优秀PHP框架

    摘要:每一个开发者都知道,拥有一个强大的框架可以让开发工作变得更加快捷安全和有效。官方网站是一款老牌的框架,现在稳定版本已经是了。官方网站是由最大的社区之一的管理开发的,也是一个开源的框架。 对于Web开发者来说,PHP是一款非常强大而又受欢迎的编程语言。世界上很多顶级的网站都是基于PHP开发的。 每一个开发者都知道,拥有一个强大的框架可以让开发工作变得更加快捷、安全和有效。在开发项目之前选...

    zombieda 评论0 收藏0
  • PHP路由性能测试

    摘要:路由控制器性能测试前言前段时间抽空写了个微型路由控制器可以在我的另一篇文章里面看到详细的介绍。上门有测试以及这几个路由控制器的性能,总体来说和在最坏的情况下表现最好。同样的测试条件。所以本次测试仅仅针对,以及。 PHP路由控制器性能测试 前言 前段时间抽空写了个微型路由控制器可以在我的另一篇文章里面看到详细的介绍。虽然在设计的时候及尽量避开了正则匹配和数组循环这种耗时的操作。尽量节省时...

    levy9527 评论0 收藏0
  • 这就是现代php该有样子(二)

    摘要:所以,是帮助您创建您的项目的测试框架,单元测试。行为驱动开发是一个来自测试驱动开发的开发过程。这种语言被称为,是用来描述被测试的预期的行为。代码将被测试并且没有异常。这些标准提出了现代编码风格。 本文来自medium----原文链接; 欢迎作客我们的php&Laravel学习群:109256050 你需要开始使用测试 这是我每天对自己说的话。像很多人一样,我不会像TDD所建议的那样测试...

    fevin 评论0 收藏0
  • PHP微型框架设计

    摘要:这些所有的结构都只是该微型框架的一个基本结构,实际上复杂的框架会有很多扩展的函数以及外部插件,可以在这个目录结构上做出相应调整。 一、框架整体分析在实现一个框架之前,我们需要了解这个框架应该达到一个怎样的效果,按照传统框架的思路,大致可以总结出以下这么几条:1.实现MVC架构,将控制、逻辑、视图层进行分离。2.封装各种函数及功能模块,实现一处编写,多处调用,减少代码冗余。3.便于扩展,...

    nihao 评论0 收藏0
  • 英特尔发布凌动C2000等多项新品 助力打造高效云计算数据中心

    摘要:新闻焦点英特尔凌动处理器产品家族是首款基于微架构的处理器,拥有种可定制化配置,面向微型服务器入门级网络和冷数据存储。全球领先的托管服务公司与已经对英特尔凌动片上系统进行了测试,并计划于下一季度在其入门级专用托管服务中部署该产品。 新闻焦点 · 英特尔凌动 C2000 处理器产品家族是首款基于 Silvermont 微架构的处理器,拥有13 种可定制化配置,面向微型服务器、入门级网络...

    junbaor 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<