在swoole中做一个仿laravel的框架,首先要确定思路:希望基于swoole扩展开发的代码在运行的时候,收到ws或者ws的时候接收tcp等消息,自动路由到某个类,同时该类可以实现加载类的依赖注入功能。Laravel作为目前市面上的主流框架之一,拥有非常方便的依赖注入功能。通常,这是如何在通常的框架中拉取Class:classa{public$bClassInstance;公共函数__construct(Classb){$classInstance=newb();}publicfunctiondoSth(){return$this->bClassInstance->xxx();}}$b=newb();$a=newa($b)$a->doSth();在Laravel中,可以省略一些实例化步骤,直接通过类型约束方法的语法在方法的形参上指定某个类的命名空间,自动实例化该类。a类{公共函数doSth(b$b){返回$b->xxx();}}要做到这一点,你必须了解PHP的反射机制。反射是一个比较冷门的类。它可以做:使用命名空间来实例化一个类,调用类的方法等。使用这个,你可以构造一个自动装箱的类。reflection=new\ReflectionClass($namespace);}catch(Exception$e){echo$namespace;}}publicfunctionbuilderController($fn,$server,$frame,$userMessage){//从路由中获取的控件名称$this->reflection->getMethod($fn)->invoke($this->autoBuilder(),$server,$frame,$userMessage);}publicfunctionbuilderTask($fn,$server,$userMessage){$this->reflection->getMethod($fn)->invoke($this->autoBuilder(),$server,$userMessage);}publicfunctionautoBuilder(){#给构造函数赋值return$this->batchInstantiation($this->getPrototypeController($this->reflection)#getstring);}受保护的最终函数getPrototypeController(\ReflectionClass$object){$prototype=false;//从反射类中批量获取原型字符串foreach($object->getConstructor()->getParameters()as$parameter){$prototype[]=$parameter->getClass()->name;}返回$prototype?:[];}protectedfinalfunctionbatchInstantiation(array$prototypeArr){foreach($prototypeArras$item){$container=newcontainer($item);$insArr[]=$container->autoBuilder();//递归注入}returnempty($prototypeArr)?$this->反射->newInstance():$this->反射->newInstanceArgs($insArr);}}有了这个简单的装箱类,我们就可以着手实现该类的路由功能了。我们先创建composer.json,输入如下内容{"require":{},"autoload":{"psr-4":{"App\\":"App/"}}}接下来,我们需要创建一个处理路由的类。该类一般用于将http请求映射到常规框架中对应类的功能。在swoole中,请求会来自长连接。那么就需要在路由类中做相应的处理。类路由{public$websocketServer;公共$模型;公共$缓存;publicfunction__construct(){$this->websocketServer=new\swoole_websocket_server("0.0.0.0","8002");}publicfunctionstart_ws(){//在这里设置一些swoole参数...//最后执行并启动swoole$this->websocketServer->start();}publicfunctionws_onMessage(\swoole_websocket_server$server,$frame){$userMessage=$this->filter_arr(json_decode($frame->data,true));如果(!$userMessage){返回false;}if(!$userMessage['type']||!$userMessage['action']){return$this->call_shell("Typeoractionnotfound!");}//使用依赖注入容器作为伪路由$App=newContainer('\App\Controller\\'.$userMessage['type']);返回$App->builderController($userMessage['action'],$server,$frame,$userMessage);最后一步是创建一个入口文件来指导路由类的执行。start_ws();
