koa2与php比较,模仿KOA,用php来写一个极简的开发框架
$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来写一个极简的开发框架相关推荐
- Koa 学习 02 Koa 实现原理和极简模拟案例
通过模拟一个极简版本的 Koa 学习实现原理. 初始化项目 # 安装 koa npm i koa 添加启动文件: // app.js const Koa = require('koa')const a ...
- koa2+html模板,lenneth -- 基于koa2 的web极简框架
说明 封装 lenneth 旨在快速方便的搭建出一个 node web 应用,不过度封装也不随波逐流,koa 的 node 是简单的,lenneth 也是. 基于 ES6+typescript 的一些 ...
- 【React组件】写一个模仿蓝湖的图片查看器
前言 最近公司让写一个可以自由拖拽放大的图片查看器,我寻思这还不简单,一顿操作猛如虎,俩小时后: 事实证明,一旦涉及到 DOM 的变换操作,如果很多细节考虑不全,抓过来就写,那基本就凉了.于是我仔细分 ...
- vue 使用fs_模仿vue-cli,手写一个脚手架
vue-cli 在vue的开发的过程中,经常会使用到vue-cli脚手架工具去生成一个项目.在终端运行命令vue create hello-world后,就会有许多自动的脚本运行. 为什么会这样运行呢 ...
- B编码与BT种子文件分析,以及模仿json-cpp写一个B编码解析器
B编码与BT种子文件分析,以及模仿json-cpp写一个B编码解析器 1.什么是B编码 2.B编码格式 3.种子文件结构 3.1.主文件结构 3.2.info结构 4.简单的例子了解一下种子文件和B编 ...
- 李白的四首诗鸿蒙胜安卓,人工智能与诗词高手,模仿《静夜思》各写首诗,竟是人工智能胜...
原标题:人工智能与诗词高手,模仿<静夜思>各写首诗,竟是人工智能胜 唐玄宗开元十四年,二十六岁的李白游玩到了扬州,烟花江南与巴蜀相隔千里.山高水远,在一个无眠的夜里,躺在旅馆的李白突然无比 ...
- 学习写一个模仿天猫网站
学习完了前端的HTML CSS JavaScript等各项技术之后,会有一个感慨,各个知识点分开都不难,但是要做出一个成型的,好看的,时尚的网页,就无从下手. 这就需要经验的积累了. 那么,写一个模仿 ...
- 老弟,来了?VUE+Nuxt.js+Koa+Vuex入门教程(一)仿写一个cnode网站
if(有工作){if(工作地址 == "深圳" || 工作地址 == "广州" ){do(请联系作者,qq:1172081598)} } 何为Nuxt.js N ...
- 自己动手模仿 springmvc 写一个 mvc框架
spring的知识那么多,看源码也不知从何看起,那应该怎么学呢?我觉得,完整的spring我们写不出来,但是一个简单的,我们还是可以实现的.自己动手去实现一个简单的spring,是学习它的最好的方式. ...
- 写一个简单的自动取款机c语言程序,C语言编程模仿银行ATM自动取款机功能
编程模仿银行ATM自动取款机功能,要求能实现以下功能: 1. 输入储户基本信息(既开户功能,开户成功需要打印储户基本信息): 2. 开户成功后打印欢迎界面,比如"开户成功,欢迎使用**银行自 ...
最新文章
- 删除数据表和清空数据表的内容(保存表结构)的SHELL脚本
- 面试官:你对MySQL高性能优化有什么规范建议?
- 如何生成项目的chm文档
- 给新手程序员的16个工作必备小妙招,省下时间去LOL吧!
- 手机MODEM 开发(26)---LTE切换和重选参数中文详解
- 重构-使代码更简洁优美:实际经验之谈(提供一技巧,让你省掉N多代码)
- 开平方的快速算法(C程序)
- 用php怎么输出一首诗,如何用一首诗总结你的2018年?
- 也谈谈如何胜任中小型公司的技术总监
- NAR|DREAM:编码RNA和药物关联的数据库
- HTML Typo.css 中文网页重设与排版
- rails consol reload!
- 上海镇保城保四金比例
- 将wav音频文件频谱分析后映射到钢琴琴键上(类似audio to midi功能)
- LXR( Linux超文本交叉代码检索工具)
- 关于jxl的一点知识
- Win10链接XP共享文件夹
- java 循环依赖_浅谈Spring解决循环依赖的三种方式
- Windows-系统问题
- 杂谈——常用的浏览器请求头User - Agent大全
热门文章
- 打开带图片的EXCEL文档反应慢 案例解析
- Android 高级学习心得及项目要点
- JS操作Cookie写入和读取实例代码
- 如何利用【百度地图API】,制作房产酒店地图?(上)——制作自定义标注和自定义信息窗口...
- 压缩JavaScript的宏
- 解决Eclipse建Maven项目module无法转换为2.5
- 1.深入分布式缓存:从原理到实践 --- 缓存为王
- 3.SRE:Google运维解密 --- 拥抱风险
- 1.Jenkins 2 权威指南 --- 简介
- 19. 配置Symfony(和环境)