api-swoole框架文檔

(一).開始

1.1下載與安裝

源碼地址:
api-swoole框架github源碼地址
api-swoole框架gitee源碼地址

需要確保運(yùn)行環(huán)境達(dá)到了以下的要求:

  • PHP >= 7.4
  • Swoole PHP 擴(kuò)展 >= 4.5
  • Redis PHP 擴(kuò)展 (如需使用 Redis 客戶端)
  • PDO PHP 擴(kuò)展 (如需使用 MySQL 客戶端)

1.2通過 Composer 創(chuàng)建項(xiàng)目

composer create-project api-swoole/skeleton

1.3啟動(dòng)

支持 HTTP 服務(wù)、WebSocket 服務(wù)、tcp服務(wù),項(xiàng)目根目錄./apiswoole.php執(zhí)行命令。

php apiswoole.php

(二).Hello World

2.1編寫一個(gè)接口

在api-swoole框架中壤短,業(yè)務(wù)主要代碼在app目錄中。里面各個(gè)命名空間對(duì)應(yīng)一個(gè)子目錄锭沟,項(xiàng)目的默認(rèn)命名空間是App致燥,創(chuàng)建項(xiàng)目后app目錄中包含Common蹭沛、Controller辽剧、Ext三個(gè)子目錄送淆,Common目錄存放函數(shù)的functions.php文件,Ext一般放置工具等怕轿。目錄結(jié)構(gòu)如下:

./
└── app
    ├── Controller # 放置接口源代碼偷崩,相當(dāng)于控制器層
    ├── Common # 公共代碼目錄,
    └── Ext# 放置工具等

當(dāng)項(xiàng)目需要新增接口時(shí)撞羽,先在./app/Controller目錄中新建hello.php文件阐斜,并用編輯器編輯代碼。

<?php

namespace App\Controller;

use Sapi\Api;

class Hello extends Api
{
    public function index()
    {
        return [
            'code' => 200,
            'data' => 'hello world'
        ];
    }
}

2.2定義路由

route/http.php路由文件中定義項(xiàng)目路由诀紊,第一個(gè)參數(shù)為定義的瀏覽器訪問地址谒出,第二個(gè)參數(shù)@前半部分為文件的完整命名空間,@后半部分為在類中調(diào)用的具體方法。

return [
    \HttpRouter("/hello", "App\Controller\Hello@index"),
];

2.3啟動(dòng)項(xiàng)目

在項(xiàng)目根目錄下執(zhí)行如下命令以非守護(hù)模式啟動(dòng)笤喳。

php apiswoole.php

默認(rèn)情況下監(jiān)聽本地的HTTP和websocket的9501端口考赛,在cmd中出現(xiàn)如下輸出信息表示項(xiàng)目啟動(dòng)成功。

[Success] Swoole: 4.5.9, PHP: 7.4.13, Port: 9501
[Success] Swoole Http Server running:http://0.0.0.0:9501
[Success] Swoole websocket Server running:ws://0.0.0.0:9501
[Success] Swoole tcp Server running:0.0.0.0:9500
[Success] Swoole udp Server running:0.0.0.0:9502

2.4訪問接口

在瀏覽器地址欄中輸入定義的路由地址莉测,地址組成http://ip網(wǎng)址:端口/定義的路由

http://127.0.0.1:9501/hello

請(qǐng)求成功返回?cái)?shù)據(jù)默認(rèn)json方式返回唧喉,包含默認(rèn)的code捣卤、msg、data字段八孝,data中數(shù)據(jù)為方法中返回的數(shù)據(jù)董朝。

{
    "code": 200,
    "msg": "success",
    "data": {
        "code": 200,
        "data": "hello world"
    }
}

(三).反向代理(Nginx + Swoole 配置)

由于 Http\Server 對(duì) HTTP 協(xié)議的支持并不完整,建議僅作為應(yīng)用服務(wù)器干跛,用于處理動(dòng)態(tài)請(qǐng)求子姜,并且在前端增加 Nginx 作為代理。(參考地址

server {
    listen 80;
    server_name swoole.test;

    location / {
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_pass http://127.0.0.1:9501;
    }
}

可以通過讀取 $request->header['x-real-ip'] 來獲取客戶端的真實(shí) IP

(四).配置

4.1配置文件

默認(rèn)config文件夾下包含conf.php楼入、db.php哥捕、events.php三個(gè)文件,conf.php放置項(xiàng)目的配置信息嘉熊,http遥赚、tcp、udp阐肤、websocket等配置凫佛。db.php負(fù)責(zé)配置MySQL、Redis連接孕惜,events.php負(fù)責(zé)定義定制特定事件注冊(cè)監(jiān)聽愧薛,現(xiàn)支持workerStart、open衫画、close毫炉、task、finish事件注冊(cè) 削罩〉夤浚可以通過DI()->config->get('conf.ws')或者\Sapi\Di::one()->config->get('conf.ws')方式讀取配置信息。

./config/
├── conf.php #http鲸郊、tcp丰榴、udp、websocket等配置
├── db.php #數(shù)據(jù)庫配置
└── events.php #定制特定事件注冊(cè)監(jiān)聽

4.2參數(shù)說明

<?php
return [
    'debug' => true,//true 調(diào)試模式 false 關(guān)閉調(diào)試
    'log' => [
        'displayConsole' => true,//控制臺(tái)打印日志秆撮,true打開 false 關(guān)閉
        'saveLog' => true,//保存日志 true 打開 false 關(guān)閉
    ],
    'udp' => [
        'host' => '0.0.0.0',//指定監(jiān)聽的ip地址
        'port' => 9502,//指定監(jiān)聽端口
        'sockType' => SWOOLE_SOCK_UDP,//指定這組 Server 的類型
        'events' => [
            ['packet', \App\Controller\UdpServe::class, 'onPacket'],//回調(diào)事件
        ],
        'settings' => [],//配置選項(xiàng)https://wiki.swoole.com/#/server/setting
    ],
    'tcp' => [
        'host' => '0.0.0.0',//指定監(jiān)聽的ip地址
        'port' => 9501,//指定監(jiān)聽端口
        'sockType' => SWOOLE_SOCK_TCP,//指定這組 Server 的類型
        'events' => [
            ['receive', \App\Controller\TcpServe::class, 'onReceive'],//回調(diào)事件
        ],
        'settings' => [],//配置選項(xiàng)https://wiki.swoole.com/#/server/setting
    ],
    'ws' => [
        'host' => '0.0.0.0',//指定監(jiān)聽的ip地址
        'port' => 9500,//指定監(jiān)聽端口
        'sockType' => SWOOLE_SOCK_TCP,//指定這組 Server 的類型
        'events' => [
            ['open', \Sapi\Events::class, 'onOpen'],
            ['message', \Sapi\Events::class, 'onMessage'],
            ['close', \Sapi\Events::class, 'onClose'],
            ['request', \Sapi\Events::class, 'onRequest'],
            ['Task', \Sapi\Events::class, 'onTask'],
            ['Finish', \Sapi\Events::class, 'onFinish'],
            ['workerStart', \Sapi\Events::class, 'onWorkerStart'],
            ['start', \Sapi\Events::class, 'onStart'],
        ],//回調(diào)事件
        'settings' => [
            'daemonize' => false,//設(shè)置 daemonize => true 時(shí)四濒,程序?qū)⑥D(zhuǎn)入后臺(tái)作為守護(hù)進(jìn)程運(yùn)行。長(zhǎng)時(shí)間運(yùn)行的服務(wù)器端程序必須啟用此項(xiàng)。如果不啟用守護(hù)進(jìn)程盗蟆,當(dāng) ssh 終端退出后戈二,程序?qū)⒈唤K止運(yùn)行
            'worker_num' => swoole_cpu_num(),
            'log_file' => 'storage/swoole',
            'log_rotation' => SWOOLE_LOG_ROTATION_DAILY,
            'log_date_format' => '%Y-%m-%d %H:%M:%S',
            'log_level' => SWOOLE_LOG_DEBUG,
            'task_worker_num' => 10,
            'enable_coroutine' => true,//是否啟用異步風(fēng)格服務(wù)器的協(xié)程支持
        ],
    ],//配置選項(xiàng)https://wiki.swoole.com/#/websocket_server?id=%e9%80%89%e9%a1%b9
    'process' => [
        [\App\Controller\Process::class, 'addProcess']
    ],//添加用戶自定義的工作進(jìn)程 https://wiki.swoole.com/#/server/methods?id=addprocess
];

4.3配置讀取示例

項(xiàng)目啟動(dòng)時(shí)在apiswoole.php已經(jīng)默認(rèn)注冊(cè)服務(wù)。

$di = DI();
$di->config = new Config("./config");

例如配置信息為conf.php,結(jié)構(gòu)為:

return [
    'debug' => true,//調(diào)試模式
    'tcp' => [
        'host' => '0.0.0.0',
        'port' => 9500,
        'sockType' => SWOOLE_SOCK_TCP,
        'events' => [
            ['receive', \App\Controller\TcpServe::class, 'onReceive'],
        ],
        'settings' => [],
    ],
]

可以使用DI()->config->get('conf.tcp')讀取配置文件

DI()->config->get('conf.tcp') #返回?cái)?shù)組

返回?cái)?shù)組數(shù)據(jù)結(jié)構(gòu):

{
    "host": "0.0.0.0",
    "port": 9500,
    "sockType": 1,
    "events": [
        [
            "receive",
            "App\\Controller\\TcpServe",
            "onReceive"
        ]
    ],
    "settings": []
}

(五).日志

根據(jù)PSR規(guī)范中詳盡定義了日志接口喳资,日志記錄在./storage/log目錄中觉吭,按照每日生成對(duì)應(yīng)日期.log日志文件。目前支持以下幾種日志記錄:

  • error: 系統(tǒng)異常類日記
  • info: 業(yè)務(wù)紀(jì)錄類日記
  • debug: 開發(fā)調(diào)試類日記
  • notice: 系統(tǒng)提示類日記
  • waring: 系統(tǒng)致命類日記

日志系統(tǒng)使用:

DI()->logger->debug("日志測(cè)試debug");  #開發(fā)調(diào)試類日記
DI()->logger->info("日志測(cè)試info");    #業(yè)務(wù)紀(jì)錄類日記
DI()->logger->notice("日志測(cè)試notice");#系統(tǒng)提示類日記
DI()->logger->waring("日志測(cè)試waring");#系統(tǒng)致命類日記
DI()->logger->error("日志測(cè)試error");  #系統(tǒng)異常類日記

./storage/log/20220906.log目錄下對(duì)應(yīng)日志:

[swoole] | [2022-09-06 01:32:05] | debug |  日志測(cè)試debug
[swoole] | [2022-09-06 01:32:05] | info |  日志測(cè)試info
[swoole] | [2022-09-06 01:32:05] | notice |  日志測(cè)試notice
[swoole] | [2022-09-06 01:32:05] | warning |  日志測(cè)試waring
[swoole] | [2022-09-06 01:32:05] | error |  日志測(cè)試error

(六).HTTP/websocket服務(wù)器(參考地址)

WebSocket\Server 繼承自 Http\Server仆邓,所以 Http\Server 提供的所有 API 和配置項(xiàng)都可以使用鲜滩。請(qǐng)參考 Http\Server 章節(jié)。

  • 設(shè)置了 onRequest 回調(diào)节值,WebSocket\Server 也可以同時(shí)作為 HTTP 服務(wù)器
  • 未設(shè)置 onRequest 回調(diào)徙硅,WebSocket\Server 收到 HTTP 請(qǐng)求后會(huì)返回 HTTP 400 錯(cuò)誤頁面

如若只想實(shí)現(xiàn)websocket服務(wù)器,則在./config/conf.php配置中刪除['request', \Sapi\Events::class, 'onRequest']即可搞疗。

6.1HTTP/websocket服務(wù)器配置

HTTP/websocket服務(wù)器配置選項(xiàng)在./config/conf.php中嗓蘑。具體配置信息可以參考Swoole文檔配置選項(xiàng)

<?php
return [
    'ws' => [
        'host' => '0.0.0.0',//監(jiān)聽地址
        'port' => 9501,//監(jiān)聽端口
        'events' => [
            ['open', \Sapi\Events::class, 'onOpen'],
            ['message', \Sapi\Events::class, 'onMessage'],
            ['close', \Sapi\Events::class, 'onClose'],
            ['request', \Sapi\Events::class, 'onRequest'],//HTTP服務(wù)器回調(diào)
            ['Task', \Sapi\Events::class, 'onTask'],
            ['Finish', \Sapi\Events::class, 'onFinish'],
            ['workerStart', \Sapi\Events::class, 'onWorkerStart'],
            ['start', \Sapi\Events::class, 'onStart'],
        ],//回調(diào)函數(shù)
        'settings' => [
            'daemonize' => false,//設(shè)置 daemonize => true 時(shí)匿乃,程序?qū)⑥D(zhuǎn)入后臺(tái)作為守護(hù)進(jìn)程運(yùn)行桩皿。長(zhǎng)時(shí)間運(yùn)行的服務(wù)器端程序必須啟用此項(xiàng)。如果不啟用守護(hù)進(jìn)程幢炸,當(dāng) ssh 終端退出后业簿,程序?qū)⒈唤K止運(yùn)行
            'worker_num' => swoole_cpu_num(),
            'log_file' => 'storage/swoole',
            'log_rotation' => SWOOLE_LOG_ROTATION_DAILY,
            'log_date_format' => '%Y-%m-%d %H:%M:%S',
            'log_level' => SWOOLE_LOG_DEBUG,
            'task_worker_num' => 10,
        ],
    ],
];

6.2HTTP路由

HTTP 服務(wù)器的路由構(gòu)建文件位于./route/http.php中。聲明具體的路由規(guī)則阳懂,第一個(gè)參數(shù)為定義的瀏覽器訪問地址梅尤,第二個(gè)參數(shù)@前半部分為文件的完整命名空間,@后半部分為在類中調(diào)用的具體方法岩调。

return [
    \HttpRouter("/", "App\Controller\App@Index"),
    \HttpRouter("/hello", "App\Controller\Hello@index"),
    \HttpRouter("聲明瀏覽器地址", "命名空間+類@類中的方法"),
];

完整的URL地址組成http://ip網(wǎng)址:端口/定義的路由巷燥。

構(gòu)建基本路由只需要一個(gè) URI 與一個(gè) 閉包,提供了一個(gè)非常簡(jiǎn)單定義路由的方法:

return [
    \HttpRouter("/start", function (\Swoole\Http\Request $request, \Swoole\Http\Response $response) {
        return 'hello';
    }),
];

6.3HTTP控制器

對(duì)應(yīng)的控制器方法默認(rèn)有兩個(gè)參數(shù) $request$reponse号枕,關(guān)于 Request 和 Response 對(duì)象完整的介紹請(qǐng)查看 Swoole 文檔:Http\Request 缰揪、 Http\Response

<?php

namespace App\Controller;

use Sapi\Api;

class Hello extends Api
{
    public function index()
    {
        return [
            'code' => 200,
            'data' => 'hello world'
        ];
    }
}

6.4接口參數(shù)規(guī)則

接口參數(shù)規(guī)則通過繼承Api類實(shí)現(xiàn),具體的定義規(guī)則通過rule()方法葱淳。

  • 一維下標(biāo)是接口類的方法名钝腺。
  • 二維下標(biāo)是接口參數(shù)名稱。
  • 三維下標(biāo)name對(duì)應(yīng)客戶端傳入的值赞厕,下標(biāo)require表示值傳入可選項(xiàng),true必須傳入艳狐,false非必須傳入。
<?php

namespace App\Controller;

use Sapi\Api;

class Auth extends Api
{

    public function rule()
    {
        return [
            'login' => [
                'username' => ['name' => 'username', 'require' => true]
            ]
        ];
    }

    public function login(\Swoole\Http\Request $request, \Swoole\Http\Response $response): array
    {

        return [
            "code" => 200,
            "msg" => "login",
            "data" => [
                'username' => $request->post['username']
            ]
        ];
    }
}

6.5websocket路由

websocket服務(wù)器的路由定義文件位于./route/websocket.php中皿桑。聲明具體的路由規(guī)則毫目,第一個(gè)參數(shù)為定義的瀏覽器訪問地址蔬啡,第二個(gè)參數(shù)@前半部分為文件的完整命名空間,@后半部分為在類中調(diào)用的具體方法镀虐。

return [
    WsRouter("/", "\App\Controller\Websocket@index"),
    WsRouter("/login", "\App\Controller\Websocket@login"),
];

完整的URL地址組成ws://ip網(wǎng)址:端口箱蟆。

6.6websocket控制器

對(duì)應(yīng)的控制器方法默認(rèn)有兩個(gè)參數(shù) $server$msg,關(guān)于 $server對(duì)象完整的介紹請(qǐng)查看 Swoole 文檔:WebSocket\Server刮便。 $msg是客戶端發(fā)送的數(shù)據(jù)信息空猜。

補(bǔ)充:websocket客戶端消息傳入格式

客戶端發(fā)送的數(shù)據(jù)信息,默認(rèn)需以json格式傳送恨旱,必須包含id辈毯、path、data三個(gè)字段窖杀。

  • id字段消息體的唯一標(biāo)識(shí)。
  • path字段是./route/websocket.php路由聲明的訪問地址裙士。
  • data字段是項(xiàng)目的具體消息參數(shù)入客,控制方法默認(rèn)的$msg
{
    "id":"918wsEMQDrj0RXxm",
    "path":"/",
    "data": {
        "username": "api-swoole"
    }
}

控制器代碼部分示例:

<?php

namespace App\Controller;

use Sapi\Api;

class Websocket extends Api
{
    public function index(\Swoole\WebSocket\Server $server, array $msg): array
    {
        return [
            'err' => 200,
            'data' => [
                'name' => 'api-swoole',
                'version' => '1.0.0',
            ]
        ];
    }
}

6.7websocket接口參數(shù)規(guī)則

接口參數(shù)規(guī)則通過繼承Api類實(shí)現(xiàn)腿椎,具體的定義規(guī)則通過rule()方法桌硫。

  • 一維下標(biāo)是接口類的方法名。
  • 二維下標(biāo)是接口參數(shù)名稱啃炸。
  • 三維下標(biāo)name對(duì)應(yīng)客戶端傳入的值铆隘,下標(biāo)require表示值傳入可選項(xiàng),true必須傳入,false非必須傳入南用。
<?php

namespace App\Controller;

use Sapi\Api;

class Websocket extends Api
{
    public function rule()
    {
        return [
            'login' => [
                'username' => ['name' => 'username', 'require' => true]
            ]
        ];
    }

    public function login(\Swoole\WebSocket\Server $server, array $msg): array
    {
        return [
            'err' => 200,
            'data' => [
                'username' => $msg['username'],
            ]
        ];
    }

}

6.8http/websocket勾子函數(shù)

Api類內(nèi)置了鉤子函數(shù)userCheck,HTTP/websocket控制器均可繼承Api類重載膀钠。例如可完成用戶身份驗(yàn)證。

首先定義聲明Base.php文件裹虫。

<?php

namespace App\Controller;

use Sapi\Api;

class Base extends Api
{
    //用戶權(quán)限驗(yàn)證
    public function userCheck()
    {
        if (true) {
            return "token過期";
        }
    }

}

然后繼承Base.php實(shí)現(xiàn)類重載肿嘲,。

<?php

namespace App\Controller;

use Sapi\Api;

class Auth extends Base
{

    public function rule()
    {
        return [
            'login' => [
                'username' => ['name' => 'username', 'require' => true]
            ]
        ];
    }

    public function login(\Swoole\Http\Request $request, \Swoole\Http\Response $response): array
    {
        return [
            "code" => 200,
            "msg" => "login",
            "data" => [
                'username' => $request->post['username']
            ]
        ];
    }
}

(七).TCP/UDP服務(wù)器

Server 可以監(jiān)聽多個(gè)端口筑公,每個(gè)端口都可以設(shè)置不同的協(xié)議處理方式雳窟,例如 80 端口處理 HTTP 協(xié)議,9500 端口處理 TCP 協(xié)議,9502 端口處理 UDP 協(xié)議匣屡。SSL/TLS 傳輸加密也可以只對(duì)特定的端口啟用封救。參考Swoole官方文檔(多端口監(jiān)聽)

7.1TCP服務(wù)器配置

TCP服務(wù)器配置選項(xiàng)在./config/conf.php中增加tcp字段。具體配置信息可以參考Swoole文檔TCP配置捣作。

    'tcp' => [
        'host' => '0.0.0.0',
        'port' => 9500,
        'sockType' => SWOOLE_SOCK_TCP,
        'events' => [
            ['receive', \App\Controller\TcpServe::class, 'onReceive'],//TCP服務(wù)器回調(diào)
        ],
        'settings' => [],
    ],

7.1UDP服務(wù)器配置

UDP服務(wù)器配置選項(xiàng)在./config/conf.php中增加udp字段誉结。具體配置信息可以參考Swoole文檔UDP配置。

    'udp' => [
        'host' => '0.0.0.0',
        'port' => 9502,
        'sockType' => SWOOLE_SOCK_UDP,
        'events' => [
            ['packet', \App\Controller\UdpServe::class, 'onPacket'],//UDP服務(wù)器回調(diào)
        ],
        'settings' => [],
    ],

(八).數(shù)據(jù)庫

Swoole 開發(fā)組采用 Hook 原生 PHP 函數(shù)的方式實(shí)現(xiàn)協(xié)程客戶端券躁,通過一行代碼就可以讓原來的同步 IO 的代碼變成可以協(xié)程調(diào)度的異步 IO搓彻,即一鍵協(xié)程化如绸。Swoole 提供的 Swoole\Server 類簇都是自動(dòng)做好的,不需要手動(dòng)做旭贬,參考 enable_coroutine怔接。具體內(nèi)容可參考Swoole官網(wǎng)一鍵協(xié)程化

框架數(shù)據(jù)庫引入simple-swoole第三方拓展包具體詳情可參考simple-swoole/db

8.1Redis

配置

Redis服務(wù)器配置選項(xiàng)在./config/db.php中。

<?php
return [
    'redis' => [
        'host' => '192.168.0.105',//Redis服務(wù)器地址
        'port' => 6379,//指定 Redis 監(jiān)聽端口
        'auth' => '',//登錄密碼
        'db_index' => 2,//指定數(shù)據(jù)庫
        'time_out' => 1,//
        'size' => 64,//連接池?cái)?shù)量
    ],
];

使用

項(xiàng)目中使用Redis

<?php

namespace App\Controller;

use App\Ext\Redis;

class RedisDemo
{
    public function setData(\Swoole\Http\Request $request, \Swoole\Http\Response $response)
    {
        $redis = new \Simps\DB\BaseRedis();
        $res = $redis->set('我是key', '我是value');
        return [
            "code" => 200,
            "msg" => "hello World!",
            "data" => [
                'res' => $res,
                'key' => $request->get['key'],
                'val' => $request->get['val'],
            ],
        ];
    }
}

8.2MySQL

8.2.1配置

MySQL服務(wù)器配置選項(xiàng)在./config/db.php中稀轨。

<?php
return [
    'mysql' => [
        'host' => '',//連接地址
        'port' => ,//連接端口
        'database' => '',//數(shù)據(jù)庫名稱
        'username' => 'root',//用戶
        'password' => '',//密碼
        'charset' => 'utf8',//字符集
        'unixSocket' => null,//
        'options' => [
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        ],
        'size' => 64 // 連接池?cái)?shù)量
    ],
];

./app/Ext/Pool.php配置連接池:

<?php

namespace App\Ext;

use Sapi\Singleton;
use Simps\DB\PDO;
use Simps\DB\Redis;

class Pool
{
    use Singleton;

    public function startPool(...$args)
    {
        $mysql_config = DI()->config->get('db.mysql');
        if (!empty($mysql_config)) {
            PDO::getInstance($mysql_config);
        }

        $redis_config = DI()->config->get('db.redis');
        if (!empty($redis_config)) {
            Redis::getInstance($redis_config);
        }
    }
}
8.2.2Medoo

simple-swoole集成了輕量級(jí)的 PHP 數(shù)據(jù)庫框架 Medoo 扼脐,使用時(shí)需要繼承 Simps\DB\BaseModel,所以使用方法和 Medoo 基本一致奋刽,具體請(qǐng)查看 Medoo 的文檔

唯一不同的是事務(wù)相關(guān)操作瓦侮,在 Medoo 中是使用 action( $callback ) 方法,而在本框架中也可以使用 action( $callback ) 方法佣谐,另外也支持以下方法

beginTransaction(); // 開啟事務(wù)
commit(); // 提交事務(wù)
rollBack(); // 回滾事務(wù)

事務(wù)示例

$this->beginTransaction();

$this->insert("user", [
    "name" => "luffy",
    "gender" => "1"
]);

$this->delete("user", [
    "id" => 2
]);

if ($this->has("user", ["id" => 23]))
{
    $this->rollBack();
} else {
    $this->commit();
}

8.2.3使用

項(xiàng)目中使用肚吏,數(shù)據(jù)庫表結(jié)構(gòu):

CREATE TABLE `user_info` (
  `uid` int(11) NOT NULL AUTO_INCREMENT,
  `nick` varchar(15) DEFAULT NULL,
  PRIMARY KEY (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=1000001 DEFAULT CHARSET=utf8;
<?php

namespace App\Controller;


class MysqlDemo
{
    public function getOne(\Swoole\Http\Request $request, \Swoole\Http\Response $response)
    {
        $uid = $request->post['uid'];

        $database = new \Simps\DB\BaseModel();
        $res = $database->select("user_info", [
            "uid",
            "nick",
        ], [
            "uid" => $uid
        ]);

        return [
            "code" => 200,
            "msg" => "MysqlDemo getOne",
            "data" => [
                'res' => $res,
                'uid' => $uid,
            ],
        ];
    }

    public function save(\Swoole\Http\Request $request, \Swoole\Http\Response $response)
    {
        $username = $request->post['username'];
        $database = new \Simps\DB\BaseModel();
        $last_user_id = $database->insert("user_info", [
            "uid" => time(),
            "nick" => $username,
        ]);

        return [
            "code" => 200,
            "msg" => "MysqlDemo save",
            "data" => [
                'last_user_id' => $last_user_id,
                'username' => $username,
            ],
        ];
    }

    public function del(\Swoole\Http\Request $request, \Swoole\Http\Response $response)
    {
        $uid = $request->post['uid'];

        $database = new \Simps\DB\BaseModel();

        $res = $database->delete("user_info", [
            "uid" => $uid
        ]);

        return [
            "code" => 200,
            "msg" => "MysqlDemo del",
            "data" => [
                'res' => $res,
                'uid' => $uid,
            ],
        ];
    }

    public function update(\Swoole\Http\Request $request, \Swoole\Http\Response $response)
    {
        $uid = $request->post['uid'];
        $username = $request->post['username'];

        $database = new \Simps\DB\BaseModel();

        $res = $database->update("user_info", [
            "nick" => $username
        ], [
            "uid" => $uid
        ]);

        return [
            "code" => 200,
            "msg" => "MysqlDemo update",
            "data" => [
                'res' => $res,
                'uid' => $uid,
                'username' => $username,
            ],
        ];
    }
}

(九).addProcess

添加一個(gè)用戶自定義的工作進(jìn)程。此函數(shù)通常用于創(chuàng)建一個(gè)特殊的工作進(jìn)程狭魂,用于監(jiān)控罚攀、上報(bào)或者其他特殊的任務(wù)。具體內(nèi)容可參考Swoole官網(wǎng)addProcess

注意事項(xiàng):

  • 創(chuàng)建的子進(jìn)程可以調(diào)用 $server 對(duì)象提供的各個(gè)方法雌澄,如 getClientList/getClientInfo/stats
  • Worker/Task 進(jìn)程中可以調(diào)用 $process 提供的方法與子進(jìn)程進(jìn)行通信
  • 在用戶自定義進(jìn)程中可以調(diào)用 $server->sendMessageWorker/Task 進(jìn)程通信
  • 用戶進(jìn)程內(nèi)不能使用 Server->task/taskwait 接口
  • 用戶進(jìn)程內(nèi)可以使用 Server->send/close 等接口
  • 用戶進(jìn)程內(nèi)應(yīng)當(dāng)進(jìn)行 while(true)(如下邊的示例) 或 EventLoop 循環(huán) (例如創(chuàng)建個(gè)定時(shí)器)斋泄,否則用戶進(jìn)程會(huì)不停地退出重啟

使用示例

添加一個(gè)用戶自定義的工作進(jìn)程,在./config/conf.php中增加process配置镐牺,如下:

'process' => [
        [\App\Controller\Process::class, 'addProcess']
    ],

控制器示例:

<?php

namespace App\Controller;

class Process
{
    //添加用戶自定義的工作進(jìn)程
    public function addProcess($server)
    {
        return new \Swoole\Process(function ($process) use ($server) {
            while (true) {
                \Co::sleep(1);
                echo "Hello, api-swoole!\r\n";
            }
        }, false, 2, 1);
    }
}

(十).訂制事件注冊(cè)

框架已默認(rèn)埋點(diǎn)workerStart炫掐、open、close睬涧、task募胃、finish五個(gè)訂制事件注冊(cè)∑枧ǎ可根據(jù)具體的業(yè)務(wù)特征在對(duì)應(yīng)的事件回調(diào)增加處理業(yè)務(wù)代碼摔认,./confg/events.php,每個(gè)事件允許有多個(gè)回調(diào)宅粥。

<?php
return [
    'workerStart' => [
        [\App\Ext\Pool::class, 'startPool'],//啟動(dòng)連接池
//        [\App\Controller\EventsDemo::class, 'workerStart'],
    ],
    'open' => [
        [\App\Controller\EventsDemo::class, 'open'],
    ],
    'close' => [
        [\App\Controller\EventsDemo::class, 'close'],
    ],
    'task' => [
        [\App\Controller\EventsDemo::class, 'task'],
    ],
    'finish' => [
        [\App\Controller\EventsDemo::class, 'finish'],
    ],
];
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末参袱,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子秽梅,更是在濱河造成了極大的恐慌抹蚀,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件企垦,死亡現(xiàn)場(chǎng)離奇詭異环壤,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)钞诡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門郑现,熙熙樓的掌柜王于貴愁眉苦臉地迎上來湃崩,“玉大人,你說我怎么就攤上這事接箫≡芏粒” “怎么了?”我有些...
    開封第一講書人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵辛友,是天一觀的道長(zhǎng)薄扁。 經(jīng)常有香客問我,道長(zhǎng)废累,這世上最難降的妖魔是什么邓梅? 我笑而不...
    開封第一講書人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮邑滨,結(jié)果婚禮上日缨,老公的妹妹穿的比我還像新娘。我一直安慰自己掖看,他們只是感情好匣距,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著乙各,像睡著了一般墨礁。 火紅的嫁衣襯著肌膚如雪幢竹。 梳的紋絲不亂的頭發(fā)上耳峦,一...
    開封第一講書人閱讀 51,301評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音焕毫,去河邊找鬼蹲坷。 笑死,一個(gè)胖子當(dāng)著我的面吹牛邑飒,可吹牛的內(nèi)容都是我干的循签。 我是一名探鬼主播,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼疙咸,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼县匠!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起撒轮,我...
    開封第一講書人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤乞旦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后题山,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體兰粉,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年顶瞳,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了玖姑。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片愕秫。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖焰络,靈堂內(nèi)的尸體忽然破棺而出戴甩,到底是詐尸還是另有隱情,我是刑警寧澤舔琅,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布等恐,位于F島的核電站,受9級(jí)特大地震影響备蚓,放射性物質(zhì)發(fā)生泄漏课蔬。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一郊尝、第九天 我趴在偏房一處隱蔽的房頂上張望二跋。 院中可真熱鬧,春花似錦流昏、人聲如沸扎即。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽谚鄙。三九已至,卻和暖如春刁绒,著一層夾襖步出監(jiān)牢的瞬間闷营,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工知市, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留傻盟,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓嫂丙,卻偏偏與公主長(zhǎng)得像娘赴,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子跟啤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容