在swoole中制作一款仿造laravel的框架
首先须要确定一下思路:我心愿基于swoole的扩大开发的代码在run起来的时候,在接管到ws或是tcp等音讯时,主动路由到某个类上,同时类能够实现加载类的依赖注入性能。目前市面上占据支流的一款框架Laravel,其中有一个依赖注入的性能十分的便捷。个别在通常的框架中拉取Class是这样做的:

class a {    public $bClassInstance;    public function __construct(Class b) {        $classInstance = new b();    }    public function doSth() {        return $this->bClassInstance->xxx();    }}$b = new b();$a = new a($b)$a->doSth();

而在Laravel中则能够省略一些实例化的步骤, 间接通过类型束缚的语法在办法的形参上指定某类的命名空间就主动实例化该类进来了。

class a {    public function doSth(b $b) {        return $b->xxx();    }}

想要实现这一点,必须要理解php的反射机制。反射是一个比拟冷门的类,他能够做到:应用namespace实例化一个类、调用类的办法等,利用这一点,能够结构一个主动装箱的类。

<?php/*** *  依赖注入容器,若要执行依赖注入,请确保类蕴含构造函数! */namespace App\Server;class Container{    public $config;    public $reflection;    public function __construct($namespace)    {        try        {            $this->reflection = new \ReflectionClass($namespace);        }        catch (Exception $e)        {            echo $namespace;        }    }    public function builderController($fn, $server, $frame, $userMessage)    {        //从route中失去的control名称        $this->reflection->getMethod($fn)->invoke($this->autoBuilder(), $server, $frame, $userMessage);    }    public function builderTask($fn, $server, $userMessage)    {        $this->reflection->getMethod($fn)->invoke($this->autoBuilder(), $server, $userMessage);    }    public function autoBuilder()    {        #对构造函数赋值        return $this->batchInstantiation($this->getPrototypeController($this->reflection)#取得字串        );    }    protected final function getPrototypeController(\ReflectionClass $object)    {        $prototype = false;        //批量从反射类中获取原型字串        foreach ($object->getConstructor()->getParameters() as $parameter)        {            $prototype[] = $parameter->getClass()->name;        }        return $prototype ?: [];    }    protected final function batchInstantiation(array $prototypeArr)    {        foreach ($prototypeArr as $item)        {            $container = new container($item);            $insArr[]  = $container->autoBuilder();//进行递归注入        }        return empty($prototypeArr) ? $this->reflection->newInstance() : $this->reflection->newInstanceArgs($insArr);    }}

有了这个繁难的装箱类后,能够着手实现类的路由性能,咱们首先创立composer.json,键入如下内容。

{    "require": {     },    "autoload": {        "psr-4": {        "App\\": "App/"        }   }}

下一步,咱们须要创立一个解决路由的类,这个类在惯例的框架中,个别用来映射http申请到对应的类的函数上,而在swoole里,申请会来自长连贯。那么在route类中则须要做相应的解决。

class Route{    public $websocketServer;    public $model;    public $cache;    public function __construct() {        $this->websocketServer = new \swoole_websocket_server("0.0.0.0", "8002");    }    public function start_ws() {        // 这里设置一些swoole的参数 ...        // 最初执行启动swoole        $this->websocketServer->start();    }       public function ws_onMessage(\swoole_websocket_server $server, $frame)    {        $userMessage = $this->filter_arr(json_decode($frame->data, true));        if (!$userMessage) {            return false;        }                if (!$userMessage['type'] || !$userMessage['action']) {            return $this->call_shell("Type or action not found! ");        }        //应用依赖注入容器做伪路由        $App = new Container('\App\Controller\\'.$userMessage['type']);        return $App->builderController($userMessage['action'], $server, $frame,$userMessage);    }    }

最初一步,创立一个入口文件,疏导路由类的执行。

<?phprequire "vendor/autoload.php";use App\Server\Route;$App = new Route();$App->start_ws();