Mix Vega 发布, 支持 Swoole、WorkerMan 的 CLI HTTP 网络框架 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
onanying
V2EX    PHP

Mix Vega 发布, 支持 Swoole、WorkerMan 的 CLI HTTP 网络框架

  •  
  •   onanying 2021-06-30 16:56:28 +08:00 1972 次点击
    这是一个创建于 1653 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Mix Vega

    Vega is a CLI HTTP web framework written in PHP support Swoole, WorkerMan

    Vega 是一个用 PHP 编写的 CLI HTTP 网络框架,支持 Swoole 、WorkerMan

    Overview

    Vega 是 MixPHP V3+ 内置的最核心的组件 (可独立使用),参考 golang gin mux 开发,它包含 Web 应用处理的大量功能 (数据库处理除外) ,包括:路由、渲染、参数获取、中间件、文件上传处理等;具有 CLI 模式下强大的兼容性,同时支持 Swoole 、WorkerMan, 并且支持 Swoole 的多种进程模型。

    推荐搭配以下数据库使用:

    源码地址

    Star 一下不迷路,下次用的时候还能找到

    技术交流

    知乎: https://www.zhihu.com/people/onanying
    官方 QQ 群:284806582, 825122875 敲门暗号:vega

    Installation

    需要先安装 Swoole 或者 WorkerMan

    composer require mix/vega 

    Quick start

    Swoole 多进程 (异步) 中使用

    <?php require __DIR__ . '/vendor/autoload.php'; $vega = new Mix\Vega\Engine(); $vega->handleF('/hello', function (Mix\Vega\Context $ctx) { $ctx->string(200, 'hello, world!'); })->methods('GET'); $http = new Swoole\Http\Server('0.0.0.0', 9501); $http->on('Request', $vega->handler()); $http->start(); 

    Swoole 单进程 (协程) 中使用

    <?php require __DIR__ . '/vendor/autoload.php'; Swoole\Coroutine\run(function () { $vega = new Mix\Vega\Engine(); $vega->handleF('/hello', function (Mix\Vega\Context $ctx) { $ctx->string(200, 'hello, world!'); })->methods('GET'); $server = new Swoole\Coroutine\Http\Server('127.0.0.1', 9502, false); $server->handle('/', $vega->handler()); $server->start(); }); 

    WorkerMan 中使用

    <?php require __DIR__ . '/vendor/autoload.php'; $vega = new Mix\Vega\Engine(); $vega->handleF('/hello', function (Mix\Vega\Context $ctx) { $ctx->string(200, 'hello, world!'); })->methods('GET'); $http_worker = new Workerman\Worker("http://0.0.0.0:2345"); $http_worker->OnMessage= $vega->handler(); $http_worker->count = 4; Workerman\Worker::runAll(); 

    访问测试

    % curl http://0.0.0.0:9501/hello hello, world! 

    路由配置

    配置 Closure 闭包路由

    $vega = new Mix\Vega\Engine(); $vega->handleF('/hello', function (Mix\Vega\Context $ctx) { $ctx->string(200, 'hello, world!'); })->methods('GET'); 

    配置 callable 路由

    class Hello { public function index(Mix\Vega\Context $ctx) { $ctx->string(200, 'hello, world!'); } } $vega = new Mix\Vega\Engine(); $vega->handleC('/hello', [new Hello(), 'index'])->methods('GET'); 

    配置路由变量

    $vega = new Mix\Vega\Engine(); $vega->handleF('/users/{id}', function (Mix\Vega\Context $ctx) { $id = $ctx->param('id'); $ctx->string(200, 'hello, world!'); })->methods('GET'); 

    配置多个 method

    $vega = new Mix\Vega\Engine(); $vega->handleF('hello', function (Mix\Vega\Context $ctx) { $ctx->string(200, 'hello, world!'); })->methods('GET', 'POST'); 

    路由前缀 (分组)

    $vega = new Mix\Vega\Engine(); $subrouter = $vega->pathPrefix('/foo'); $subrouter->handleF('/bar1', function (Mix\Vega\Context $ctx) { $ctx->string(200, 'hello, world!'); })->methods('GET'); $subrouter->handleF('/bar2', function (Mix\Vega\Context $ctx) { $ctx->string(200, 'hello1, world!'); })->methods('GET'); 

    参数获取

    请求参数

    方法名称 描述
    $ctx->param(string $key): string 获取路由参数
    $ctx->query(string $key): string 获取 url 参数,包含路由参数
    $ctx->defaultQuery(string $key, string $default): string 获取 url 参数,可配置默认值
    $ctx->getQuery(string $key): string or null 获取 url 参数, 可判断是否存在
    $ctx->postForm(string $key): string 获取 post 参数
    $ctx->defaultPostForm(string $key, string $default): string 获取 post 参数,可配置默认值
    $ctx->getPostForm(string $key): string or null 获取 post 参数,可判断是否存在

    Headers, Cookies, Uri ...

    方法名称 描述
    $ctx->contentType(): string 请求类型
    $ctx->header(string $key): string 请求头
    $ctx->cookie(string $name): string cookies
    $ctx->uri(): UriInterface 完整 uri
    $ctx->rawData(): string 原始包数据

    客户端 IP

    方法名称 描述
    $ctx->clientIP(): string 从反向代理获取用户真实 IP
    $ctx->remoteIP(): string 获取远程 IP

    上传文件处理

    方法名称 描述
    $ctx->formFile(string $name): UploadedFileInterface 获取上传的第一个文件
    $ctx->multipartForm(): UploadedFileInterface[] 获取上传的全部文件

    文件保存

    $file = $ctx->formFile('img'); $targetPath = '/data/uploads/' . $file->getClientFilename(); $file->moveTo($targetPath); 

    请求上下文

    请求当中需要保存一些信息,比如:会话、JWT 载荷等。

    方法名称 描述
    $ctx->set(string $key, $value): void 设置值
    $ctx->get(string $key): mixed or null 获取值
    $ctx->mustGet(string $key): mixed or throws 获取值或抛出异常

    中断执行

    abort 执行后,会停止执行后面的全部代码,包括中间件。

    $vega = new Mix\Vega\Engine(); $vega->handleF('/users/{id}', function (Mix\Vega\Context $ctx) { if (true) { $ctx->string(401, 'Unauthorized'); $ctx->abort(); } $ctx->string(200, 'hello, world!'); })->methods('GET'); 

    响应处理

    方法名称 描述
    $ctx->status(int $code): void 设置状态码
    $ctx->setHeader(string $key, string $value): void 设置 header
    $ctx->setCookie(string $name, string $value, int $expire = 0, ...): void 设置 cookie
    $ctx->redirect(string $location, int $code = 302): void 重定向

    JSON 请求与输出

    获取 JSON 请求数据

    $vega = new Mix\Vega\Engine(); $vega->handleF('/users', function (Mix\Vega\Context $ctx) { $obj = $ctx->getJSON(); if (!$obj) { throw new \Exception('Parameter error'); } var_dump($obj); $ctx->JSON(200, [ 'code' => 0, 'message' => 'ok' ]); })->methods('POST'); 

    mustGetJSON 自带有效性检查,以下代码等同于上面

    $vega = new Mix\Vega\Engine(); $vega->handleF('/users', function (Mix\Vega\Context $ctx) { $obj = $ctx->mustGetJSON(); var_dump($obj); $ctx->JSON(200, [ 'code' => 0, 'message' => 'ok' ]); })->methods('POST'); 

    JSONP 处理

    $vega = new Mix\Vega\Engine(); $vega->handleF('/jsonp', function (Mix\Vega\Context $ctx) { $ctx->JSONP(200, [ 'code' => 0, 'message' => 'ok' ]); })->methods('GET'); 

    HTML 视图渲染

    创建视图文件 foo.php

    <p>id: <?= $id ?>, name: <?= $name ?></p> <p>friends:</p> <ul> <?php foreach($friends as $name): ?> <li><?= $name ?></li> <?php endforeach; ?> </ul> 

    配置视图路径,并响应 html

    $vega = new Mix\Vega\Engine(); $vega->withHTMLRoot('/data/project/views'); $vega->handleF('/html', function (Mix\Vega\Context $ctx) { $ctx->HTML(200, 'foo', [ 'id' => 1000, 'name' => '小明', 'friends' => [ '小花', '小红' ] ]); })->methods('GET'); 

    设置中间件

    给某个路由配置中间件,可配置多个

    $vega = new Mix\Vega\Engine(); $func = function (Mix\Vega\Context $ctx) { // do something $ctx->next(); }; $vega->handleF('/hello', $func, function (Mix\Vega\Context $ctx) { $ctx->string(200, 'hello, world!'); })->methods('GET'); 

    配置全局中间件,即便没有匹配到路由也会执行

    $vega = new Mix\Vega\Engine(); $vega->use(function (Mix\Vega\Context $ctx) { $ctx->next(); }); 

    前置中间件

    $vega->use(function (Mix\Vega\Context $ctx) { // do something $ctx->next(); }); 

    后置中间件

    $vega->use(function (Mix\Vega\Context $ctx) { $ctx->next(); // do something }); 

    404 自定义

    $vega = new Mix\Vega\Engine(); $vega->use(function (Mix\Vega\Context $ctx) { try{ $ctx->next(); } catch (Mix\Vega\Exception\NotFoundException $ex) { $ctx->string(404, 'New 404 response'); $ctx->abort(); } }); 

    500 全局异常捕获

    $vega = new Mix\Vega\Engine(); $vega->use(function (Mix\Vega\Context $ctx) { try{ $ctx->next(); } catch (\Throwable $ex) { $ctx->string(500, 'New 500 response'); $ctx->abort(); } }); 

    License

    Apache License Version 2.0, http://www.apache.org/licenses/

    1 条回复    2021-06-30 17:41:51 +08:00
    mzsongyan
        1
    mzsongyan  
       2021-06-30 17:41:51 +08:00
    很不错,下个项目试试!
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3345 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 04:45 PVG 12:45 LAX 20:45 JFK 23:45
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86