easyswoole - 基于swoole扩展实现的一款高性能php框架

控制器

功能介紹

毫無疑問,控制器層是負責(zé)處理客戶端請求,轉(zhuǎn)發(fā)給響應(yīng)模型,并將結(jié)果返回給客戶端。EasySwoole 使用了對象池復(fù)用模式,降低對象創(chuàng)建、銷毀的開銷,注入 requestresponse 對象來完成客戶端與服務(wù)端之間的交互。

示例

App/HttpController/ 目錄下增加文件 User.php

代碼

<?php
/**
 * @CreateTime:   2020/8/19 12:30 上午
 * @Author:       huizhang  <2788828128@qq.com>
 * @Copyright:    copyright(2020) Easyswoole all rights reserved
 * @Description:  用戶控制器
 */
namespace App\HttpController;

use EasySwoole\Http\AbstractInterface\Controller;

class User extends Controller
{

    /**
     * 用戶信息
     *
     * @return string
     * CreateTime: 2020/8/19 12:37 上午
     */
    public function userInfo()
    {
        // 獲取 get 參數(shù)
        $name = $this->request()->getQueryParam('name');

        // 輸出到終端
        var_dump($name);

        // 返回給客戶端
        $this->response()->write($name . PHP_EOL);

        // return 返回的值會讓框架在此進行控制器方法調(diào)度,將繼續(xù)執(zhí)行 User 控制器類的 requestTotal 方法 
        return '/User/requestTotal';
    }

    /**
     * 接口請求量
     *
     * CreateTime: 2020/8/19 12:37 上午
     */
    public function requestTotal()
    {
        $this->response()->write('請求數(shù)+1' . PHP_EOL);

        // 還可以 return,但不要兩個方法互相調(diào)用,會導(dǎo)致死循環(huán)
    }

    /**
     * 此控制器拋異常時會執(zhí)行此方法
     *
     * @param \Throwable $throwable
     * @throws \Throwable
     * CreateTime: 2020/8/19 12:48 上午
     */
    public function onException(\Throwable $throwable): void
    {
        parent::onException($throwable); // TODO: Change the autogenerated stub
    }

    /**
     * gc 方法將在執(zhí)行完 afterAction 方法之后自動調(diào)用,可自行覆蓋實現(xiàn)其他的 gc 回收邏輯
     *
     * CreateTime: 2020/8/19 12:52 上午
     */
    public function gc()
    {
        parent::gc(); // TODO: Change the autogenerated stub
    }

    /**
     * 當(dāng)控制器方法執(zhí)行結(jié)束之后將調(diào)用該方法,可自行覆蓋該方法實現(xiàn)數(shù)據(jù)回收等邏輯
     *
     * @param string|null $actionName
     * CreateTime: 2020/8/19 12:51 上午
     */
    public function afterAction(?string $actionName): void
    {
        parent::afterAction($actionName); // TODO: Change the autogenerated stub
    }

    /**
     * 當(dāng)請求方法未找到時,自動調(diào)用該方法,可自行覆蓋該方法實現(xiàn)自己的邏輯
     *
     * @param string|null $action
     * CreateTime: 2020/8/19 12:51 上午
     */
    public function actionNotFound(?string $action)
    {
        parent::actionNotFound($action); // TODO: Change the autogenerated stub
    }

    /**
     * 所有控制器請求都會先經(jīng)過該方法,如果此方法返回 false 則請求不繼續(xù)往下執(zhí)行,可用于權(quán)限驗證
     *
     * @param string|null $action
     * @return bool|null
     * CreateTime: 2020/8/19 12:52 上午
     */
    public function onRequest(?string $action): ?bool
    {
        return parent::onRequest($action); // TODO: Change the autogenerated stub
    }

}

執(zhí)行過程

啟動 easyswoole

php easyswoole.php server start

訪問

curl http://localhost:9501/user/userInfo?name=easyswoole

執(zhí)行結(jié)果

服務(wù)端輸出

?  doc-new git:(master) ? php easyswoole.php server start
#!/usr/bin/env php
  ______                          _____                              _
 |  ____|                        / ____|                            | |
 | |__      __ _   ___   _   _  | (___   __      __   ___     ___   | |   ___
 |  __|    / _` | / __| | | | |  \___ \  \ \ /\ / /  / _ \   / _ \  | |  / _ \
 | |____  | (_| | \__ \ | |_| |  ____) |  \ V  V /  | (_) | | (_) | | | |  __/
 |______|  \__,_| |___/  \__, | |_____/    \_/\_/    \___/   \___/  |_|  \___|
                          __/ |
                         |___/

main server                   SWOOLE_WEB
listen address                0.0.0.0
listen port                   9501
worker_num                    8
reload_async                  true
max_wait_time                 3
document_root                 /Users/guoyuzhao/sites/doc-new/Static
enable_static_handler         true
pid_file                      /Users/guoyuzhao/sites/doc-new/Temp/pid.pid
log_file                      /Users/guoyuzhao/sites/doc-new/Log/swoole.log
user                          guoyuzhao
swoole version                4.5.2
php version                   7.4.8
easyswoole version            3.4.0-dev
run mode                      dev
temp dir                      /Users/guoyuzhao/sites/doc-new/Temp
log dir                       /Users/guoyuzhao/sites/doc-new/Log
string(10) "easyswoole"

客戶端輸出

?  ssh curl http://localhost:9501/user/userInfo\?name\=easyswoole

easyswoole
請求數(shù)+1

控制器方法

easyswoole 在控制器基類中實現(xiàn)了幾個通用方法,當(dāng)然用戶也可根據(jù)需要進行方法重寫實現(xiàn)自己的邏輯

onRequest

所有控制器請求都會先經(jīng)過該方法,如果此方法返回 false 則請求不繼續(xù)往下執(zhí)行,可用于權(quán)限驗證

protected function onRequest(?string $action): ?bool
{
    return true;
}

onException

當(dāng)執(zhí)行控制器方法拋異常時會調(diào)用該方法,可自行覆蓋該方法實現(xiàn)異常捕獲等邏輯

protected function onException(\Throwable $throwable): void
{
    throw $throwable;
}

afterAction

當(dāng) action 執(zhí)行結(jié)束后調(diào)用該方法,可自行覆蓋該方法實現(xiàn)數(shù)據(jù)回收等邏輯

protected function afterAction(?string $actionName): void
{

}

actionNotFound

當(dāng)請求方法未找到時,自動調(diào)用此方法

protected function actionNotFound(?string $action)
{
    $class = static::class;
    $this->writeJson(\EasySwoole\Http\Message\Status::CODE_NOT_FOUND,null,"{$class} has not action for {$action}");
}

gc

gc 方法在 afterAction 方法執(zhí)行完后調(diào)用

protected function gc()
{
    //恢復(fù)默認(rèn)值
    foreach ($this->defaultProperties as $property => $value) {
        $this->{$property} = $value;
    }
}

注意事項

  • 只有第一次請求時才會調(diào)用構(gòu)造函數(shù)
  • 對象池模式只重置非靜態(tài) public 屬性
  • 對象池復(fù)用模式只針對單一進程,多個 worker 進程不共享
  • 文件夾、文件、類名為大駝峰,變量與類方法小駝峰(規(guī)范)
  • action 返回的字符串將會被 url 解析規(guī)則以及 route 路由規(guī)則解析
  • 兩個 actionreturn 不能互相調(diào)用,否則將導(dǎo)致死循環(huán)

另外注意:在控制器類的方法(onRequest/action 等方法)中創(chuàng)建子協(xié)程,在子協(xié)程中使用 $this 的相關(guān)屬性值時必須使用 use 引入,不使用 use 引入時將導(dǎo)致協(xié)程上下文數(shù)據(jù)錯亂。

錯誤使用示例:

下面以在 Index 控制器類中的 action(index) 中使用為示例:

<?php
/**
 * This file is part of EasySwoole.
 *
 * @link http://www.zbjtqy.com
 * @document http://www.zbjtqy.com
 * @contact http://www.zbjtqy.com/Preface/contact.html
 * @license https://github.com/easy-swoole/easyswoole/blob/3.x/LICENSE
 */

namespace App\HttpController;

use EasySwoole\Http\AbstractInterface\Controller;
use EasySwoole\Utility\Random;

class Index extends Controller
{
    public function index()
    {
        // 設(shè)置請求標(biāo)識
        $requestFlag = Random::number(3);
        $this->request()->withAttribute('requestFlag', $requestFlag);
        $rq = '第 ' . $this->request()->getRequestParam('times') . ' 次請求:';
        var_dump($rq . $this->request()->getAttribute('requestFlag'));
        go(function () {
            $rq = '第 ' . $this->request()->getRequestParam('times') . ' 次請求:';
            go(function () {
                $rq = '第 ' . $this->request()->getRequestParam('times') . ' 次請求:';
                \co::sleep(2);
                var_dump($rq . $this->request()->getAttribute('requestFlag'));
            });
            \co::sleep(4);
            // 【這里的數(shù)據(jù)會錯亂】
            var_dump($rq . $this->request()->getAttribute('requestFlag'));
        });
        $this->response()->write('this is index!' . $this->request()->getRequestParam('times'));
    }
}

然后我們訪問 http://127.0.0.1:9501/?times=1(示例請求地址),隔 1s 后我們再次訪問 http://127.0.0.1:9501/?times=2(示例請求地址),發(fā)現(xiàn)出現(xiàn)如下運行結(jié)果,控制臺輸出結(jié)果:

string(21) "第 1 次請求:765"
string(21) "第 1 次請求:765"
string(21) "第 2 次請求:823"
string(21) "第 1 次請求:823"
string(21) "第 2 次請求:823"
string(21) "第 2 次請求:823"

發(fā)現(xiàn)和我們想象中的完全不一樣,第 1 次請求掛載的數(shù)據(jù)被“污染”了,因為 EasySwoole 控制器采用的是對象池模式。

正確使用方式如下:

<?php
/**
 * This file is part of EasySwoole.
 *
 * @link http://www.zbjtqy.com
 * @document http://www.zbjtqy.com
 * @contact http://www.zbjtqy.com/Preface/contact.html
 * @license https://github.com/easy-swoole/easyswoole/blob/3.x/LICENSE
 */

namespace App\HttpController;

use EasySwoole\Http\AbstractInterface\Controller;
use EasySwoole\Utility\Random;

class Index extends Controller
{
    public function index()
    {
        // 設(shè)置請求標(biāo)識
        $requestFlag = Random::number(3);
        $this->request()->withAttribute('requestFlag', $requestFlag);
        $rq = '第 ' . $this->request()->getRequestParam('times') . ' 次請求:';
        var_dump($rq . $this->request()->getAttribute('requestFlag'));
        go(function () use ($rq, $requestFlag) {
            go(function () use ($rq, $requestFlag) {
                \co::sleep(2);
                var_dump($rq . $requestFlag);
            });
            \co::sleep(4);
            // 【這里的數(shù)據(jù)會錯亂】
            var_dump($rq . $requestFlag);
        });
        $this->response()->write('this is index!' . $this->request()->getRequestParam('times'));
    }
}

然后我們訪問 http://127.0.0.1:9501/?times=1(示例請求地址),隔 1s 后我們再次訪問 http://127.0.0.1:9501/?times=2(示例請求地址),發(fā)現(xiàn)出現(xiàn)如下運行結(jié)果,控制臺輸出結(jié)果:

string(21) "第 1 次請求:690"
string(21) "第 1 次請求:690"
string(21) "第 2 次請求:820"
string(21) "第 1 次請求:690"
string(21) "第 2 次請求:820"
string(21) "第 2 次請求:820"

發(fā)現(xiàn)數(shù)據(jù)正常了。

主站蜘蛛池模板: 消泡剂_有机硅消泡剂_分散剂_流平剂_氟碳表面活性剂-上海梓意化工有限公司 | 云南亿华工贸有限公司-云南护栏网-云南锌钢护栏-昆明市政护栏-工地护栏-昆明护栏网厂家 | 上海便携式液体_日本理音液体_HACH液体颗粒计数器,metone尘埃粒子计数器-上海翰森科学仪器有限公司 | 消防安装_消防安装施工_消防施工_北京消防安装公司-亿杰(北京)消防工程有限公司 | 耐油橡胶接头,耐酸碱橡胶接头,耐高温橡胶接头|淞江集团 | 友联智能|RFID应用服务供应商|专注RFID行业解决方案|RFID数据采集-助力行业数字化转型 | 饲料设备_饲料加工设备_饲料成套加工设备专业提供商-河南杰昌机械设备有限公司 | 危废处理_危废处置_危废处理公司-江苏绿瑞特环境科技股份有限公司 | 铁三角话筒-思美音频处理器-艾伦赫赛数字调音台-北京盛世音盟电子科技有限公司 | 平邑衡器厂--临沂衡器--电子汽车衡 -- 十佳知名品牌企业 | 聚丙烯酰胺,聚合氯化铝,重金属捕捉剂,污泥调理剂,活性氧化铝,生石灰,反渗透阻垢剂,工业葡萄糖,硫酸铝,果壳活性炭,柱状活性炭,蜂窝活性炭,石英砂,锰砂-北京雁归来环保科技有限公司-以真诚为立足之本,以质量为生存之本,愿与海内外同仁共创双赢。雁归来人一路走来,气贯长虹,勇锐盖过怯弱,进取压倒苟安!我们紧扣时代脉搏,专注水处理、继往开来! | 河北高新技术企业认定,沧州商标注册,沧州9001质量管理体系认证,沧州高新技术企业认定,沧州体系认证,沧州商标续展,沧州版权登记,河北国瑞企业管理咨询有限公司 | 破碎机设备-锤式颚式反击式圆锥移动冲击式破碎机厂家-成都大宏立机器公司 | 郑州冷却塔_河南冷却塔-河南金创制冷设备有限公司 | 深圳彩盒印刷-纸盒包装-不干胶标签印刷-深圳印刷厂家-深圳贝的印刷 | 山东正奇塑料机械有限公司,山东塑料机械,水带机组,塑料管材机,山东吹膜机组厂家,山东农膜机厂家 山东长青石油液压机械有限公司-致力于石油机械设备的研发制造,提供定制服务 | 环球医网 | 带来健康生活...| 立式/卧式/潜水/液下/螺杆/耐磨/渣浆泵|泥浆泵|离心泵,厂家 - 河北聚盛泵业制造有限公司 | 行情网 - 钢材行情,金属行情,废金属行情,农产品行情,化工行情,水泥行情 | 莱湾科技-智能会议室|多功能|多媒体|音视频|无纸化|远程视频会议室运维 | 莫非传媒官网-江西知名的网络营销推广服务平台南昌网络公司,专业网络公关,品牌危机处理,网站SEO优化,微信朋友圈广告,网站建设,南昌莫非文化传媒有限公司 | 昆明护栏网厂家_隔离栅_围栏网_石笼网「13年生产经验」-云南北辛商贸 | 无塔供水设备_无负压供水设备_变频供水设备_净化过滤设备_加油站油罐_S/F双层油罐_开封市东方供水设备有限公司 | 中科联航(江苏)-信息化监理|信息化咨询|信息系统项目管理|信息系统工程监理公司 | 烟台广告公司-烟台仁和图文广告制作有限公司 | 装修公司-吉诚装饰公司官网| 莫非传媒官网-江西知名的网络营销推广服务平台南昌网络公司,专业网络公关,品牌危机处理,网站SEO优化,微信朋友圈广告,网站建设,南昌莫非文化传媒有限公司 | 兰州沙盘模型公司_兰州模型公司_兰州沙盘模型厂家_地形沙盘制作_兰州沙盘模型制作公司 | 铝合金线棒生产厂家-提供第三代精益管,防静电工作台定制与批发-宁波杰艾逖仓储设备有限公司 | 上海物业管理_写字楼物业管理_厂房物业管理_上海企福物业管理有限公司 | 新中式家具,广东新中式家具,广州新中式家具,佛山新中式家具,顺德新中式家具,乐从新中式家具,新中式家具厂家直销--唐明雅居 | 天津印刷_天津印刷厂_天津印刷公司_天津包装盒厂家_天津包装盒印刷厂_七层共挤膜厂家_彩色印刷_画册印刷_礼品盒定做 _七层共挤膜_食品真空袋-欢迎访问嘉联包装官网! | 湖州搬家公司_档案搬迁_货物运输_钟点搬运价格「湖州蓝天家政综合服务有限公司」 | 自动_链条式_电动推杆_电动开窗器厂家_山东鑫宏玺智能科技有限公司 | 思行科技-珠海小程序开发-珠海网站建设-珠海APP开发-江门小程序开发-江门网站建设-江门APP开发 | 中国江苏国际经济技术合作集团有限公司-致力于做大做强国际工程、国内工程、国际贸易和城镇投资 中国建材信息总网-中国建材行业权威的信息资讯平台 | 实木中药柜,实木中药斗,木制中药柜,木制中药柜的价格,实木中草药柜,安国美佳中药柜厂家 | 深圳LED显示屏厂家_室内户外LED显示屏_彩屏电子有限公司 | 铸造厂-铸铝-铸铜-铝合金铸造-重力铸造-翻砂铸造-[剑锋机械配件]专业东莞|深圳铸造厂 | 活性炭吸附设备,UV光氧废气处理设备,破碎机专用除尘器,催化燃烧设备厂家-河北碧清环保设备有限公司 | 亦庄律师法律咨询|北京亦庄律师在线|-亦庄律师事务所 |