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

只是为了好玩——Slim使用的是Swoole

时间:2023-03-30 06:07:08 PHP

SlimSlim,这是一个遵循PSR(PSR-7)规范的微框架。作者说:Slim是一个PHP微框架,可以帮助您快速编写简单但功能强大的Web应用程序和API。Slim的核心是一个调度程序,它接收HTTP请求、调用适当的回调例程并返回HTTP响应。就是这样。一个Http响应对象。Slim实际上为我们做了两件事。路由分发依赖注入框架很小,所以其他部分(比如db操作,模板引擎)可能需要自己实现,但是slim可以让你通过依赖注入轻松组装起来。其他功能变为苗条。快速入门:['addContentLengthHeader'=>false,]];$app=new\Slim\App($config);//定义应用路由$app->get('/hello/{name}',function($request,$response,$args){return$response->write("Hello".$args['name']);});//运行app$app->run();request表示当前请求对象,response表示当前响应对象,$args为数组占位符的键值对。访问/hello/salamander会输出HellosalamanderaddingdependencyDB是我自己封装的一个PDO操作类。$config=['settings'=>['addContentLengthHeader'=>false,]];$app=new\Slim\App($config);$container=$app->getContainer();$container['db']=function($c){$dbHost='localhost';$dbName='测试';$dbConf=['dsn'=>"mysql:dbname={$dbName};host={$dbHost}",'username'=>"root",'password'=>"******",'字符集'=>'utf8'];$db=new\App\Library\DB();$db->__setup($dbConf);return$db;};//定义应用路由$app->get('/user/{uid}','App\Controller\IndexController:index');IndexController类命名空间App\Controller;classIndexController{protected$container;公共函数__construct(ContainerInterface$container){$this->container=$container;}publicfunctionindex($request,$response,$args){$info=$this->container['db']->fetch('SELECTnameFROMuserWHEREuid=:uid',['uid'=>$args['uid']]);echo"用户名是".$信息['姓名'];}}IndexController类是composer自动加载的(代码中没有写):"autoload":{"psr-4":{"App\\":"app/"}},在代码中可以找到依赖容器的注入发生在类被实例化时。在执行IndexController的index方法时,我们从$container中取出db依赖。此时,注册的回调函数被调用,返回实例。因为在使用的时候就实例化了,所以这叫做延迟实例化。结合SwooleSwoole可以让PHP常驻内存,并且提供了HttpServer的功能,所以Slim和Swoole没有冲突。ThinkSlim使用当前路由(例如/user/2,没有查询字符串)和http方法来找到正确的回调函数。这些数量的Slim是从哪里来的?绝对是$_SERVER。查看slim源码:run()方法:publicfunctionrun($silent=false){$response=$this->container->get('response');尝试{ob_start();$response=$this->process($this->container->get('request'),$response);}catch(InvalidMethodException$e){$response=$this->processInvalidMethod($e->getRequest(),$response);}最后{$output=ob_get_clean();}if(!empty($output)&&$response->getBody()->isWritable()){$outputBuffering=$this->container->get('settings')['outputBuffering'];if($outputBuffering==='prepend'){//前置输出缓冲区内容$body=newHttp\Body(fopen('php://temp','r+'));$body->write($output.$response->getBody());$response=$response->withBody($body);}elseif($outputBuffering==='append'){//附加输出缓冲区内容$response->getBody()->write($output);}}$response=$this->finalize($response);如果(!$silent){$this->respond($response);}return$response;}找到$request对象就从容器中取出来了,那么$request是怎么注册的呢??,然后查看App类的构造函数,最后发现在Container类的构造函数中有一个registerDefaultServices()方法:privatefunctionregisterDefaultServices($userSettings){/***此服务必须返回一个数组或一个*\ArrayAccess实例。**@returnarray|\ArrayAccess*/$this['settings']=function()use($userSettings,$defaultSettings){returnnewCollection(array_merge($defaultSettings,$userSettings));}};$defaultProvider=newDefaultServicesProvider();$defaultProvider->register($this);}检查$defaultProvider->register()方法:publicfunctionregister($container){if(!isset($container['environment'])){/***这个服务必须返回\Slim\In的共享实例*接口\Http\环境接口。**@returnEnvironmentInterface*/$container['environment']=function(){returnnewEnvironment($_SERVER);}};}if(!isset($container['request'])){/***PSR-7请求对象**@paramContainer$container**@returnServerRequestInterface*/$container['request']=function($container){returnRequest::createFromEnvironment($container->get('environment'));};}//...可以看到$request对象是通过Request::createFromEnvironment方法构造的,需要从容器中取出环境依赖,而环境依赖是通过构造一个Environment对象获取的,它刚好放入$_SERVER查看Environment类的源码,可以发现它继承了Collection类。Collection的构造函数如下:publicfunction__construct(array$items=[]){$this->replace($items);}由上可知,我们主要是注册一个自定义的环境依赖。原始的$_SERVER信息可以从swoole的$request->server获取简单实现server.phpon("start",function($server){echo"Swoolehttp服务器启动于http://0.0.0.0:8888\n";});$http->on("request",function($request,$response){//实例化应用$config=['settings'=>['addContentLengthHeader'=>false,]];$config['environment']=function()use($request){$server=[];foreach($request->serveras$key=>$value){$server[strtoupper($key)]=$value;}returnnewEnvironment($server);};$app=new\Slim\App($config);//注册路由需要APP.'/routes.php';//运行app$slimResponse=$app->run(true);$headers=$slimResponse->getHeaders();foreach($headersas$name=>$values){$response->header($name,implode(",",$values));}$response->header("X-Powered-By","Salamander");$response->end($slimResponse->getBody());});$http->start();注意$request->server中的key都是小写的,所以这里转换成routes.php(在App目录下)get('/',function(Request$request,Response$response){$response->getBody()->write('HelloSalamander');return$response;});$app->get('/user/{uid}',function(Request$request,Response$response,$args){$response->getBody()->write('HelloUser:'.$args['uid']);返回$response;});测试access/access/user/45包下载测试百度云盘提示:环境基于docker,运行docker-composeup讨论Github上的Issue