Light-php 基于swoole的高性能php框架

??Light-php是一個(gè)基于swoole的高性能php框架,輕量的封裝和易用性糠涛,使它在中小型高性能項(xiàng)目中有著出色的表現(xiàn)援奢。項(xiàng)目地址:https://github.com/woann/Light-php

環(huán)境要求

依賴 說(shuō)明
PHP >= 7.2 推薦7.2
Swoole >= 4.2.9 從2.0.12開始不再支持PHP5 推薦4.2.9+
Linux 大部分的linux系統(tǒng)都可以 推薦centos

安裝教程

1-1.通過(guò)Composer安裝(packagist),此方式安裝版本可能不是最新的,出現(xiàn)此問(wèn)題請(qǐng)用1-2方式安裝忍捡。

composer create-project woann/light-php -vvv

1-2.通過(guò)Git安裝集漾。

git clone https://github.com/woann/Light-php.git

2.重命名.env.example文件為.env,并配置

3.項(xiàng)目根目錄下執(zhí)行 php bin\light start 啟動(dòng)服務(wù)

image.png

4.瀏覽器訪問(wèn)http://127.0.0.1:9521 即可看到hello world的輸出切黔。至此,框架就安裝完成了具篇。

配置文件

1.Light-php的配置文件在/config目錄下纬霞,框架集成了全局環(huán)境配置文件/.env,常規(guī)配置都在.env文件中進(jìn)行配置。

2./config/app.php,框架主要配置文件主要用來(lái)配置swoole擴(kuò)展相關(guān)參數(shù)驱显。

3./config/databases.php,數(shù)據(jù)庫(kù)配置文件诗芜,配置了數(shù)據(jù)庫(kù)連接相關(guān)參數(shù)。

4./config/hook.php,配置鉤子(鉤子主要用來(lái)將業(yè)務(wù)邏輯和通知服務(wù)分離)埃疫。

5./config/redis.php,redis配置文件伏恐,配置了redis連接相關(guān)參數(shù)。

6./config/route.php,路由配置文件熔恢。

7.以上配置文件具體參數(shù)意義在代碼中都有注釋脐湾,這里不做更多介紹

路由

以下是一個(gè)路由示例/config/route.php,包含http路由和websocket路由(注意:路由中叙淌,控制器參數(shù)為控制器的簡(jiǎn)寫,實(shí)際控制器文件應(yīng)在后追加Controller)

return [
    'm'             => 'index',    //默認(rèn)模塊
    'c'             => 'index',    //默認(rèn)控制器
    'a'             => 'init',     //默認(rèn)操作
    'ext'           => '.html',    //偽靜態(tài)后綴    例如 .html
    'http'          =>  [          //http路由
        //uri-----請(qǐng)求方法----模塊/控制器/方法----[中間件]
        '/'     => ['GET','Index/Index/index','Test'],
        'test/'    => ['GET','Index/Index/ws']
    ],
    'websocket'     =>  [           //websocket路由
        //uri----模塊/控制器/方法
        'ws' => 'Index/WebSocket/index',
    ]
];

中間件

中間件文件應(yīng)建立在/app/Middleware目錄下愁铺,類名與文件名要一致鹰霍,并實(shí)現(xiàn)Lib\Middleware接口,中間件處理方法名必須為handle,過(guò)濾后如果通過(guò)最終返回結(jié)果必須為true茵乱。示例:

<?php
namespace app\Middleware;

use Lib\Middleware;
class Test implements Middleware{
    public function handle($request)
    {
        //在此處理中間件判斷邏輯茂洒,
        //...

        //程序最后通過(guò)驗(yàn)證后,返回true;
        return true;
    }
}

控制器

1.創(chuàng)建控制器瓶竭,控制器文件應(yīng)建立在/app/Controller目錄下督勺,類名與文件名要一致,必須繼承Lib\Controller類斤贰,示例:

<?php
namespace app\Controllers\Index;

use Lib\Controller;

class IndexController extends Controller {
    //普通輸出
    public function index()
    {
        return 'hello world';
    }
    
    //輸出json
    public function index1()
    {
        return $this->json(["code" => 200, "msg" => "success"]);
    }
    
    //調(diào)用模板
     public function index2()
    {
        $a = "test";
        //輸出/app/resources/views目錄下index.blade.php模板智哀,并攜帶參數(shù)$a。支持用 . 拼接模板路徑(和laravel中模板引擎部分一樣)
        return $this->view("index",["a" => $a]);
        //也可以直接調(diào)用view函數(shù)
        return view("admin.index",["a" => $a]);
    }
    
}

2.獲取參數(shù)

    //獲取get參數(shù)
    $this->request->get()荧恍;//獲取所有g(shù)et參數(shù):array
    $this->request->get("name")瓷叫;//傳參字符串,獲取key為name的參數(shù):string
    $this->request->get(["name","age"])送巡;//傳參數(shù)組摹菠,獲取key為name和age的參數(shù):array
    
    //獲取post參數(shù)
    $this->request->post();//獲取所有g(shù)et參數(shù):array
    $this->request->post("name")骗爆;//傳參字符串次氨,獲取key為name的參數(shù):string
    $this->request->post(["name","age"]);//傳參數(shù)組摘投,獲取key為name和age的參數(shù):array
    
    //獲取上傳文件
    $this->request->getFiles();//獲取所有
    $this->request->getFile("image");//獲取指定文件
    //文件上傳
    //--------文件----[路徑](基于/resources/uploads/)---[新文件名](默認(rèn)為隨機(jī)生成)
    uploadFile($file,"banner","test.png");//上傳文件方法 開發(fā)者也可以不用此方法自己寫上傳操作

鉤子

1.創(chuàng)建鉤子煮寡,鉤子文件應(yīng)建立在/app/Hook目錄下虹蓄,類名與文件名要一致,必須繼承Lib\BaseHook類洲押,示例:

<?php
namespace app\Hook;

use Lib\BaseHook;
use Lib\Log;
class TestHook extends BaseHook {
    public function start($name,$ip,$port)
    {
        //當(dāng)server啟動(dòng)時(shí)執(zhí)行此鉤子
        Log::getInstance()->write('INFO',$name,"啟動(dòng)成功","{$ip}:{$port}","at",date('Y-m-d H:i:s'));
    }
    public function open($server,$fd){
        //可以在此執(zhí)行websocket鏈接成功后綁定用戶id和fd的操作
    }
    public function close($server,$fd){
        //可以在此執(zhí)行websocket關(guān)閉鏈接后解綁用戶id和fd的操作
    }
}

2.在鉤子配置文件/app/config/hook.php中注冊(cè)鉤子

<?php
return [
    //Server::onStart
    'start'     => [
        [\app\Hook\TestHook::class,'start'],
    ],
    //Server::onOpen
    'open'      => [
        [\app\Hook\TestHook::class,'open'],
    ],
    //Server::onClose
    'close'     => [
        [\app\Hook\TestHook::class,'close'],
    ],
];

3.使用鉤子

//--獲取鉤子服務(wù)實(shí)例----監(jiān)聽方法--鉤子名---參數(shù)(...)------
Hook::getInstance()->listen("start",$this->name,$this->config['ip'],$this->config['port']);

Task任務(wù)

1.創(chuàng)建Task類武花,Task文件應(yīng)建立在/app/Task目錄下,類名與文件名要一致杈帐,示例:

<?php
namespace app\Task;

class Notice{
    /**
     * 給所有在線客戶端發(fā)送消息
     * @param $fd       發(fā)起請(qǐng)求的FD
     * @param $data     要發(fā)送的內(nèi)容
     *
     * @return bool
     */
    public function ToAll($fd,$data){
        $fds = [] ;//用來(lái)存放所有客戶端fd
        foreach($this->server->connections as $client_fd){
            if($fd != $client_fd && $this->server->exist($client_fd)){
                //循環(huán)向客戶端輸出消息体箕,排除掉發(fā)送者fd
                $this->server->push($client_fd,$data);
                $fds[] = $client_fd;
            }
        }
        return "已向[".join(",",$fds)."]發(fā)送通知內(nèi)容:".$data;
    }
}

2.控制器中投遞任務(wù)

//---------獲取task示例----賦值server---------------投遞任務(wù)---任務(wù)類------------方法------------參數(shù)
\Lib\Task::getInstance()->setServer($this->server)->delivery(\app\Task\Notice::class,'ToAll',[1,"123"]);

WebSocket

1.開啟websocket server,配置.env文件SERVER_TYPE=websocket,此配置環(huán)境下可同時(shí)監(jiān)聽http

2.定義路由挑童,參考文檔路由部分累铅,在路由配置文件/config/route.phpwebsocket索引下定義路由站叼。

3.控制器示例

<?php
namespace app\Controllers\Index;

use Lib\WsController;
class WebSocketController extends WsController {
    public function index()
    {
        //給客戶端發(fā)送消息
        //$this->>fd 客戶端唯一標(biāo)示
        //$this->>server websocket server對(duì)象(此對(duì)象提供的功能參考swoole文檔)
        //
        $data = "哈哈哈我是一條消息";
        $data2 = "這是一條通過(guò)task任務(wù)群發(fā)消息";
        $this->server->push($this->fd,$data);
        //投遞異步任務(wù)
        $this->task->delivery (\app\Task\Notice::class,'ToAll',[$this->fd,$data2]);
    }

}

4.前端略過(guò)(視圖目錄中有一個(gè)ws.blade.php文件娃兽,可以用來(lái)測(cè)試websocket)...

數(shù)據(jù)庫(kù)

數(shù)據(jù)庫(kù)采用laravel框架的Illuminate\Database,熟悉laravel的小伙伴可極速上手尽楔。

1.查詢構(gòu)建器投储,參考文檔

<?php
namespace app\Controllers\Index;

use Lib\Controller;
use Lib\DB;
class IndexController extends Controller {

    public function index()
    {
        $res = DB::table('user')->where('id',1)->first();
    }
    
}

2.Model,參考文檔

namespace app\Models;

use Illuminate\Database\Eloquent\Model;
class User extends Model
{
    protected $table = 'user';
}

壓力測(cè)試

  • 調(diào)用框架內(nèi)一個(gè)json輸出方法,輸出如下內(nèi)容:
{
    "word": "hello world"
}
image.png
  • 方法內(nèi)有一條查詢語(yǔ)句的壓力測(cè)試
 public function index(){
        $res = DB::table('user')->where('id',"=","1")->first();
        return $this->json($res);
    }
image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末阔馋,一起剝皮案震驚了整個(gè)濱河市玛荞,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌呕寝,老刑警劉巖勋眯,帶你破解...
    沈念sama閱讀 211,042評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異下梢,居然都是意外死亡客蹋,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門孽江,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)讶坯,“玉大人,你說(shuō)我怎么就攤上這事竟坛∶龉” “怎么了?”我有些...
    開封第一講書人閱讀 156,674評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵担汤,是天一觀的道長(zhǎng)涎跨。 經(jīng)常有香客問(wèn)我,道長(zhǎng)崭歧,這世上最難降的妖魔是什么隅很? 我笑而不...
    開封第一講書人閱讀 56,340評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上叔营,老公的妹妹穿的比我還像新娘屋彪。我一直安慰自己,他們只是感情好绒尊,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評(píng)論 5 384
  • 文/花漫 我一把揭開白布畜挥。 她就那樣靜靜地躺著,像睡著了一般婴谱。 火紅的嫁衣襯著肌膚如雪蟹但。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,749評(píng)論 1 289
  • 那天谭羔,我揣著相機(jī)與錄音华糖,去河邊找鬼。 笑死瘟裸,一個(gè)胖子當(dāng)著我的面吹牛客叉,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播话告,決...
    沈念sama閱讀 38,902評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼兼搏,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了沙郭?” 一聲冷哼從身側(cè)響起向族,我...
    開封第一講書人閱讀 37,662評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎棠绘,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體再扭,經(jīng)...
    沈念sama閱讀 44,110評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡氧苍,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了泛范。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片让虐。...
    茶點(diǎn)故事閱讀 38,577評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖罢荡,靈堂內(nèi)的尸體忽然破棺而出赡突,到底是詐尸還是另有隱情,我是刑警寧澤区赵,帶...
    沈念sama閱讀 34,258評(píng)論 4 328
  • 正文 年R本政府宣布惭缰,位于F島的核電站,受9級(jí)特大地震影響笼才,放射性物質(zhì)發(fā)生泄漏漱受。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望器紧。 院中可真熱鬧虚婿,春花似錦弓叛、人聲如沸峡钓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)癌压。三九已至蛹批,卻和暖如春撰洗,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背般眉。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工了赵, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人甸赃。 一個(gè)月前我還...
    沈念sama閱讀 46,271評(píng)論 2 360
  • 正文 我出身青樓柿汛,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親埠对。 傳聞我的和親對(duì)象是個(gè)殘疾皇子络断,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評(píng)論 2 348