首先需要确定一下思路:我希望基于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);
} }

最后一步,创建一个入口文件,引导路由类的执行。

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

在swoole中制作一款仿制laravel的框架的更多相关文章

  1. 使用 CSS & jQuery 制作一款漂亮的多彩时钟

    大家可能见过各种各样的时钟效果,比如多年前非常流行的 Flash 制作的各种新奇的动画时钟,现在的 Web 开发者们又开始应用 CSS3 和 Canvas 等最新技术来实现.而今天这里要分享的这款漂亮 ...

  2. 教你如何用PS制作多款按钮UI设计教程

    教你如何用PS制作多款按钮UI设计教程 本文教大家制作按钮的方法 LV. ★ 初入设计,学做按钮.只会套个底色,加个阴影,字体纯白,小聪明的弄个圆角. LV. ★★(描边.字体.内阴影) 看了很多案例 ...

  3. 用Html5结合Qt制作一款本地化EXE游戏-太空大战(Space War)

    本次来说一说如何利用lufylegend.js引擎制作一款html5游戏后将其通过Qt转换成EXE程序.步骤其实非常简单,接下来就一步步地做一下解释和说明. 首先我们来开发一个有点类似于太空大战的游戏 ...

  4. 如何制作一款HTML5 RPG游戏引擎——第五篇,人物&人物特效

    上一次,我们实现了对话类,今天就来做一个游戏中必不可少的——人物类. 当然,你完全是可以自己写一个人物类,但是为了方便起见,还是决定把人物类封装到这个引擎里. 为了使这个类更有意义,我还给人物类加了几 ...

  5. 如何制作一款HTML5 RPG游戏引擎——第四篇,情景对话

    今天我们来实现情景对话.这是一个重要的功能,没有它,游戏将变得索然无味.所以我们不得不来完成它. 但是要知道,使用对话可不是一件简单的事,因为它内部的东西很多,比如说人物头像,人物名称,对话内容... ...

  6. 如何制作一款HTML5 RPG游戏引擎——第三篇,利用幕布切换场景

    开言: 在RPG游戏中,如果有地图切换的地方,通常就会使用幕布效果.所谓的幕布其实就是将两个矩形合拢,直到把屏幕遮住,然后再展开直到两个矩形全部移出屏幕. 为了大家做游戏方便,于是我给这个引擎加了这么 ...

  7. 如何制作一款HTML5 RPG游戏引擎——第二篇,烟雨+飞雪效果

    今天我们来实现烟雨+飞雪效果.首先来说,一款经典的RPG游戏难免需要加入天气的变化.那么为了使我们的RPG游戏引擎更完美,我们就只好慢慢地实现它. 本文为该系列文章的第二篇,如果想了解以前的文章可以看 ...

  8. cocos2d-x之道~制作第一款文字游戏(二)

    在 cocos2d-x之道~制作第一款文字游戏(一)中,使用cocos2d-x把主界面显示出来.分别有每一个级别提供的初始短语TileView,和目标短语TargetView.初步接触了cocos2d ...

  9. 在mysql数据库中制作千万级测试表

    在mysql数据库中制作千万级测试表 前言: 最近准备深入的学一下mysql,包括各种引擎的特性.性能优化.分表分库等.为了方便测试性能.分表等工作,就需要先建立一张比较大的数据表.我这里准备先建一张 ...

随机推荐

  1. C++中main函数的返回值一定要是int

    因为大学上课时候,经常是在主函数中做处理,直接用cout语句输出到显示设备,所以一直在用void main(). 直到后面具体编程的时候,才发现void main()这种用法是按 C89(C语言的早期 ...

  2. Petrozavodsk Summer Training Camp 2016H(多标记线段树)题解

    题意: \(n\)个草,第\(0\)天种下,高度都为\(0\),每个草每天长高\(a_i\).现给出\(q\)询问,每次给出第\(b_i\)天,然后把高于\(d_i\)的全削成\(d_i\),每次问你 ...

  3. HDU 4511 小明系列故事——女友的考验 (AC自动机 + DP)题解

    题意:从 1 走到 n,要求所走路径不能出现给定的路径,求最短路 思路:因为要求不能出现给定路径,那么我可以求助ac自动机完成判断. 我们可以在build的时候标记哪些路径不能出现,显然下面这种表示后 ...

  4. 记一次 lampiao渗透(Drupal+脏牛提权)

    vulnhub|渗透测试lampiao 题记 最近在打靶机,发现了一个挺有意思的靶机,这里想跟大家分享一下. 环境准备 vulnhub最近出的一台靶机 靶机(https://www.vulnhub.c ...

  5. μC/OS-III---I笔记2---实钟节拍

    所谓时钟节拍,就是CPU以固定的频率产生中断,可以看做是系统的心跳.内核利用这个时钟节拍来管理各个任务的一些时间管理比如延时,定时,超时检测,时间轮片调度等.时钟节拍的频率一般10Hz--1000Hz ...

  6. 力扣1689. 十-二进制数的最少数目-C语言实现-中等难度题

    题目 传送门 如果一个十进制数字不含任何前导零,且每一位上的数字不是 0 就是 1 ,那么该数字就是一个 十-二进制数 .例如,101 和 1100 都是 十-二进制数,而 112 和 3001 不是 ...

  7. js optional chaining operator

    js optional chaining operator js 可选链 可选链操作符( ?. )允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效. ?. 操作符的功能类似于 ...

  8. document.URL vs window.location.href All In One

    document.URL vs window.location.href All In One document.URL 与 window.location.href 两者有啥区别 document. ...

  9. 【目标检测】用Fast R-CNN训练自己的数据集超详细全过程

    目录: 一.环境准备 二.训练步骤 三.测试过程 四.计算mAP 寒假在家下载了Fast R-CNN的源码进行学习,于是使用自己的数据集对这个算法进行实验,下面介绍训练的全过程. 一.环境准备 我这里 ...

  10. Python学习笔记_有关tuple的几点强调

    创建只有一个元素的tuple,需要用逗号结尾消除歧义 a_tuple = (2,) tuple中的list mixed_tuple = (1, 2, ['a', 'b']) print("m ...