$ctx->body.='>m1';

$ctx->next();

$ctx->body.='>m1 end';

});

$app->use('Middleware2');

$app->run();

基本上跟koa类似,先new一个app对象,使用use方法添加中间件,支持闭包或外部文件。

$ctx支持注入所需的各种参数,方便各中间件共用。

完整代码

//app.php

classApp{

private$m=array();

private$ctx=array();

functionnext(){

$f=$this->c->current();

if(!$f)return;

$this->c->next();

$f($this);

}

functionrun(){

$this->c=$this->_gen();

$this->next();

}

privatefunction_gen(){

foreach($this->mas$v){

yield$v;

}

}

privatefunction_add($m){

if(!empty($this->m)&&$this->m[count($this->m)-1]===false)return;

if(!$m){

$this->m[]=false;

}elseif(($minstanceofClosure)){

$this->m[]=$m;

}else{

$m=$this->_load($m);

if(!function_exists($m)){

thrownewException('middleware error');

}

else$this->m[]=$m;

}

}

//处理文件加载,返回执行函数(如需要,可加入命名空间处理)

privatefunction_load($m){

$f='./middleware/'.$m.".php";

if(!file_exists($f))thrownewException('middleware error');

require$f;

return$m;

}

function__call($m,$v){

if('use'==$m){

$p=isset($v[0])?$v[0]:'';

$this->_add($p);

}else{

thrownewException('method not exists');

}

}

function__set($k,$v){

print_r($k);

print_r($v);

$this->ctx[$k]=$v;

}

function__get($k){

returnisset($this->ctx[$k])?$this->ctx[$k]:NULL;

}

}

//app.php

classApp{

private$m=array();

private$ctx=array();

functionnext(){

$f=$this->c->current();

if(!$f)return;

$this->c->next();

$f($this);

}

functionrun(){

$this->c=$this->_gen();

$this->next();

}

privatefunction_gen(){

foreach($this->mas$v){

yield$v;

}

}

privatefunction_add($m){

if(!empty($this->m)&&$this->m[count($this->m)-1]===false)return;

if(!$m){

$this->m[]=false;

}elseif(($minstanceofClosure)){

$this->m[]=$m;

}else{

$m=$this->_load($m);

if(!function_exists($m)){

thrownewException('middleware error');

}

else$this->m[]=$m;

}

}

//处理文件加载,返回执行函数(如需要,可加入命名空间处理)

privatefunction_load($m){

$f='./middleware/'.$m.".php";

if(!file_exists($f))thrownewException('middleware error');

require$f;

return$m;

}

function__call($m,$v){

if('use'==$m){

$p=isset($v[0])?$v[0]:'';

$this->_add($p);

}else{

thrownewException('method not exists');

}

}

function__set($k,$v){

print_r($k);

print_r($v);

$this->ctx[$k]=$v;

}

function__get($k){

returnisset($this->ctx[$k])?$this->ctx[$k]:NULL;

}

}

没错,这就是全部的代码。

代码讲解 use方法 use可以加入闭包或外部文件,且php5不支持use作为方法名,这里用 __call来实现重载,当调用use时由 __call来调用私有的 _add方法。

_add对传进来的参数作判断,如果是字符串,表示外部加载,则去判断文件和处理函数是否存在和有效,然后将处理函数加到中间件队列。

这里面如果use()传递空参数,表示忽略后面的中间件。

run方法 添加完中间件后,执行 $app->run()方法运行,来看看是怎么执行的:

调用私有的_gen来生成一个生成器,该生成器可以迭代返回队列中的中间件处理函数。 调用next方法执行下一个中间件(这里即第一个入口)

2.1 调用生成器的current方法获得当前的处理函数

2.2 执行该函数(传递$this作为参数,即$ctx),并调用生成器的next方法后移到下一个处理函数

直到生成器没有返回时结束。 中间件中需调用 $ctx->next()将控制权交到下一个中间件,从而迭代完所有的中间件。

__get和 __set方法 提供了 __get和 __set方法,是方便在中间件中使用$ctx直接设置和访问未经定义的值。如:

$ctx->body='hello';

$ctx->tplName='a.tpl';

$ctx->body='hello';

$ctx->tplName='a.tpl';

That is all

本文来源网络,侵立删!

koa2与php比较,模仿KOA,用php来写一个极简的开发框架相关推荐

  1. Koa 学习 02 Koa 实现原理和极简模拟案例

    通过模拟一个极简版本的 Koa 学习实现原理. 初始化项目 # 安装 koa npm i koa 添加启动文件: // app.js const Koa = require('koa')const a ...

  2. koa2+html模板,lenneth -- 基于koa2 的web极简框架

    说明 封装 lenneth 旨在快速方便的搭建出一个 node web 应用,不过度封装也不随波逐流,koa 的 node 是简单的,lenneth 也是. 基于 ES6+typescript 的一些 ...

  3. 【React组件】写一个模仿蓝湖的图片查看器

    前言 最近公司让写一个可以自由拖拽放大的图片查看器,我寻思这还不简单,一顿操作猛如虎,俩小时后: 事实证明,一旦涉及到 DOM 的变换操作,如果很多细节考虑不全,抓过来就写,那基本就凉了.于是我仔细分 ...

  4. vue 使用fs_模仿vue-cli,手写一个脚手架

    vue-cli 在vue的开发的过程中,经常会使用到vue-cli脚手架工具去生成一个项目.在终端运行命令vue create hello-world后,就会有许多自动的脚本运行. 为什么会这样运行呢 ...

  5. B编码与BT种子文件分析,以及模仿json-cpp写一个B编码解析器

    B编码与BT种子文件分析,以及模仿json-cpp写一个B编码解析器 1.什么是B编码 2.B编码格式 3.种子文件结构 3.1.主文件结构 3.2.info结构 4.简单的例子了解一下种子文件和B编 ...

  6. 李白的四首诗鸿蒙胜安卓,人工智能与诗词高手,模仿《静夜思》各写首诗,竟是人工智能胜...

    原标题:人工智能与诗词高手,模仿<静夜思>各写首诗,竟是人工智能胜 唐玄宗开元十四年,二十六岁的李白游玩到了扬州,烟花江南与巴蜀相隔千里.山高水远,在一个无眠的夜里,躺在旅馆的李白突然无比 ...

  7. 学习写一个模仿天猫网站

    学习完了前端的HTML CSS JavaScript等各项技术之后,会有一个感慨,各个知识点分开都不难,但是要做出一个成型的,好看的,时尚的网页,就无从下手. 这就需要经验的积累了. 那么,写一个模仿 ...

  8. 老弟,来了?VUE+Nuxt.js+Koa+Vuex入门教程(一)仿写一个cnode网站

    if(有工作){if(工作地址 == "深圳" || 工作地址 == "广州" ){do(请联系作者,qq:1172081598)} } 何为Nuxt.js N ...

  9. 自己动手模仿 springmvc 写一个 mvc框架

    spring的知识那么多,看源码也不知从何看起,那应该怎么学呢?我觉得,完整的spring我们写不出来,但是一个简单的,我们还是可以实现的.自己动手去实现一个简单的spring,是学习它的最好的方式. ...

  10. 写一个简单的自动取款机c语言程序,C语言编程模仿银行ATM自动取款机功能

    编程模仿银行ATM自动取款机功能,要求能实现以下功能: 1. 输入储户基本信息(既开户功能,开户成功需要打印储户基本信息): 2. 开户成功后打印欢迎界面,比如"开户成功,欢迎使用**银行自 ...

最新文章

  1. 删除数据表和清空数据表的内容(保存表结构)的SHELL脚本
  2. 面试官:你对MySQL高性能优化有什么规范建议?
  3. 如何生成项目的chm文档
  4. 给新手程序员的16个工作必备小妙招,省下时间去LOL吧!
  5. 手机MODEM 开发(26)---LTE切换和重选参数中文详解
  6. 重构-使代码更简洁优美:实际经验之谈(提供一技巧,让你省掉N多代码)
  7. 开平方的快速算法(C程序)
  8. 用php怎么输出一首诗,如何用一首诗总结你的2018年?
  9. 也谈谈如何胜任中小型公司的技术总监
  10. NAR|DREAM:编码RNA和药物关联的数据库
  11. HTML Typo.css 中文网页重设与排版
  12. rails consol reload!
  13. 上海镇保城保四金比例
  14. 将wav音频文件频谱分析后映射到钢琴琴键上(类似audio to midi功能)
  15. LXR( Linux超文本交叉代码检索工具)
  16. 关于jxl的一点知识
  17. Win10链接XP共享文件夹
  18. java 循环依赖_浅谈Spring解决循环依赖的三种方式
  19. Windows-系统问题
  20. 杂谈——常用的浏览器请求头User - Agent大全

热门文章

  1. 打开带图片的EXCEL文档反应慢 案例解析
  2. Android 高级学习心得及项目要点
  3. JS操作Cookie写入和读取实例代码
  4. 如何利用【百度地图API】,制作房产酒店地图?(上)——制作自定义标注和自定义信息窗口...
  5. 压缩JavaScript的宏
  6. 解决Eclipse建Maven项目module无法转换为2.5
  7. 1.深入分布式缓存:从原理到实践 --- 缓存为王
  8. 3.SRE:Google运维解密 --- 拥抱风险
  9. 1.Jenkins 2 权威指南 --- 简介
  10. 19. 配置Symfony(和环境)