当前位置: 首页 > 后端技术 > PHP

模仿KOA,用php写一个极简开发框架

时间:2023-03-30 02:11:04 PHP

nodejskoa可以说是非常流行了,尤其是它的“洋葱模型”,用过的人应该印象深刻,我们来试试用php实现一个吧。注:本文为PHPec框架最原始版本。PHPec是在此基础上精心编写的极简轻量级开发框架。除了提供中间件调用方式外,还提供常用的自动路由功能。初始版本已在github上发布。欢迎有意者了解并提出建议,也欢迎star。地址:https://github.com/tim1020/PHPec预期用途首先来看看我是如何使用“这个框架”的?require'app.php';$app=newApp();$app->use(function($ctx){$ctx->body.='>m1';$ctx->next();$ctx->body.='>m1end';});$app->use('Middleware2');$app->run();基本和koa类似,先新建一个app对象,使用use方法添加中间件,支持闭包或者外部文件。$ctx支持注入所需的各种参数,方便所有中间件共享。完整代码//app.phpclassApp{private$m=array();私人$ctx=array();函数next(){$f=$this->c->current();如果(!$f)返回;$this->c->next();$f($这个);}functionrun(){$this->c=$this->_gen();$这个->下一个();}privatefunction_gen(){foreach($this->mas$v){yield$v;}}私有函数_add($m){if(!empty($this->m)&&$this->m[count($this->m)-1]===false)return;如果(!$m){$this->m[]=false;}elseif(($minstanceofClosure)){$this->m[]=$m;}else{$m=$this->_load($m);if(!function_exists($m)){thrownewException('中间件错误');}else$this->m[]=$m;}}//处理文件加载,返回执行函数(如果需要,添加命名空间处理)privatefunction_load($m){$f='./middleware/'.$m.".php";if(!file_exists($f))thrownewException('middlewareerror');需要$f;返回$m;}函数__call($m,$v){if('use'==$m){$p=isset($v[0])?$v[0]:'';$this->_add($p);}else{thrownewException('方法不存在');}}函数__set($k,$v){$this->ctx[$k]=$v;}函数__get($k){返回isset($this->ctx[$k])?$this->ctx[$k]:NULL;}}没错,这就是全部代码。代码说明了使用方法。use可以添加到闭包或外部文件中,php5不支持use作为方法名。这里使用__call实现重载,调用use时使用__call调用私有的_add方法。_add判断传入的参数,如果是字符串,则表示外部加载,然后判断文件和处理函数是否存在且有效,然后将处理函数添加到中间件队列中。这里,如果use()传了一个空参数,就意味着后面的中间件被忽略了。run方法添加中间件后,执行$app->run()方法,看看是如何执行的:调用private_gen生成生成器,生成器可以迭代返回队列函数中的中间件处理。调用next方法执行下一个中间件(这里是第一个入口)2.1调用generator当前方法获取当前处理函数2.2执行函数(传递$this作为参数,即$ctx),调用生成器方法的下一个移动到下一个处理程序函数,直到生成器不返回并结束。在中间件中,需要调用$ctx->next()将控制权交给下一个中间件,从而迭代所有的中间件。__get和__set方法提供了__get和__set方法,方便使用$ctx直接设置和访问中间件中未定义的值。如:$ctx->body='hello';$ctx->tplName='a.tpl';就这些