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

🚀Light-php是一個基於swoole的高性能php框架,輕量的封裝和易用性,使它在中小型高性能項目中有着出色的表現。

Latest Stable Version
Latest Unstable Version
Total Downloads
License
Php Version
Swoole Version

文檔目錄

環境要求

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

安裝教程

1-1.通過Composer安裝(packagist),此方式安裝版本可能不是最新的,出現此問題請用1-2方式安裝。

composer create-project woann/light-php -vvv

1-2.通過Git安裝。

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

2.重命名.env.example文件爲.env,並配置

3.項目根目錄下執行 php bin\light start 啓動服務

image.png

4.瀏覽器訪問http://127.0.0.1:9521 即可看到hello world的輸出。至此,框架就安裝完成了。

配置文件

1.Light-php的配置文件在/config目錄下,框架集成了全局環境配置文件/.env,常規配置都在.env文件中進行配置。

2./config/app.php,框架主要配置文件主要用來配置swoole擴展相關參數。

3./config/databases.php,數據庫配置文件,配置了數據庫連接相關參數。

4./config/hook.php,配置鉤子(鉤子主要用來將業務邏輯和通知服務分離)。

5./config/redis.php,redis配置文件,配置了redis連接相關參數。

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

7.以上配置文件具體參數意義在代碼中都有註釋,這裏不做更多介紹

路由

以下是一個路由示例/config/route.php,包含http路由和websocket路由(注意:路由中,控制器參數爲控制器的簡寫,實際控制器文件應在後追加Controller)

return [
    'm'             => 'index',    //默認模塊
    'c'             => 'index',    //默認控制器
    'a'             => 'init',     //默認操作
    'ext'           => '.html',    //僞靜態後綴    例如 .html
    'http'          =>  [          //http路由
        //uri-----請求方法----模塊/控制器/方法----[中間件]
        '/'     => ['GET','Index/Index/index','Test'],
        'test/'    => ['GET','Index/Index/ws']
    ],
    'websocket'     =>  [           //websocket路由
        //uri----模塊/控制器/方法
        'ws' => 'Index/WebSocket/index',
    ]
];

中間件

中間件文件應建立在/app/Middleware目錄下,類名與文件名要一致,並實現Lib\Middleware接口,中間件處理方法名必須爲handle,過濾後如果通過最終返回結果必須爲true。示例:

<?php
namespace app\Middleware;

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

        //程序最後通過驗證後,返回true;
        return true;
    }
}

控制器

1.創建控制器,控制器文件應建立在/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"]);
    }
    
    //調用模板
     public function index2()
    {
        $a = "test";
        //輸出/app/resources/views目錄下index.blade.php模板,並攜帶參數$a。支持用 . 拼接模板路徑(和laravel中模板引擎部分一樣)
        return $this->view("index",["a" => $a]);
        //也可以直接調用view函數
        return view("admin.index",["a" => $a]);
    }
    
}

2.獲取參數

    //獲取get參數
    $this->request->get();//獲取所有get參數:array
    $this->request->get("name");//傳參字符串,獲取key爲name的參數:string
    $this->request->get(["name","age"]);//傳參數組,獲取key爲name和age的參數:array
    
    //獲取post參數
    $this->request->post();//獲取所有get參數:array
    $this->request->post("name");//傳參字符串,獲取key爲name的參數:string
    $this->request->post(["name","age"]);//傳參數組,獲取key爲name和age的參數:array
    
    //獲取上傳文件
    $this->request->getFiles();//獲取所有
    $this->request->getFile("image");//獲取指定文件
    //文件上傳
    //--------文件----[路徑](基於/resources/uploads/)---[新文件名](默認爲隨機生成)
    uploadFile($file,"banner","test.png");//上傳文件方法 開發者也可以不用此方法自己寫上傳操作

鉤子

1.創建鉤子,鉤子文件應建立在/app/Hook目錄下,類名與文件名要一致,必須繼承Lib\BaseHook類,示例:

<?php
namespace app\Hook;

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

2.在鉤子配置文件/app/config/hook.php中註冊鉤子

<?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.使用鉤子

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

Task任務

1.創建Task類,Task文件應建立在/app/Task目錄下,類名與文件名要一致,示例:

<?php
namespace app\Task;

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

2.控制器中投遞任務

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

WebSocket

1.開啓websocket server,配置.env文件SERVER_TYPE=websocket,此配置環境下可同時監聽http

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

3.控制器示例

<?php
namespace app\Controllers\Index;

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

}

4.前端略過(視圖目錄中有一個ws.blade.php文件,可以用來測試websocket)...

數據庫

數據庫採用laravel框架的Illuminate\Database,熟悉laravel的小夥伴可極速上手。

1.查詢構建器,參考文檔

<?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';
}

壓力測試

  • 調用框架內一個json輸出方法,輸出如下內容:
{
    "word": "hello world"
}

image.png

  • 方法內有一條查詢語句的壓力測試
 public function index(){
        $res = DB::table('user')->where('id',"=","1")->first();
        return $this->json($res);
    }

image.png

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章