??
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ù)
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.php
,websocket
索引下定義路由站叼。
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"
}
- 方法內(nèi)有一條查詢語(yǔ)句的壓力測(cè)試
public function index(){
$res = DB::table('user')->where('id',"=","1")->first();
return $this->json($res);
}