原本是去年学习swoole课程留下的笔记,想着可能有些人需要,便分享给大家。
首先,先使用swoole建个http服务器,这里可以专门写个http.php作为启动服务脚本
$http = new swoole_http_server("127.0.0.1", 9501);
然后设置参数:
$http->set([
'enable_static_handler' => true,
'document_root' =>__DIR__."/../public/static",
'worker_num'=>5,
]);
在使用当进程启动时就会执行的函数:
$http->on('WorkerStart', function(swoole_server $server, $worker_id) {
// 定义应用目录
define('APP_PATH', __DIR__ . '/../application/');
// ThinkPHP 引导文件
// 加载基础文件
require __DIR__ . '/../thinkphp/base.php';
});
加载tp5的基础文件以及定义应用目录,实际的路径根据自己项目来写一个监听request的方法,将tp5的url,request,post,get,cookie等转换成原生的,由于每个进程创建的变量参数在进程存在时不会被撤销,于是有以下三种方案
/**
* 解决上一次输入的变量还存在的问题
* 方案一:if(!empty($_GET)) {unset($_GET);}
* 方案二:$http-close();把之前的进程kill,swoole会重新启一个进程,重启会释放内存,把上一次的资源包括变量等全部清空
* 方案三:$_SERVER = []
*/:
$http->on('request', function ($request, $response)use($http) {
$_SERVER = [];
//server
if(isset($request->server)) {
foreach($request->server as $k => $v) {
$_SERVER[strtoupper($k)] = $v;
}
}
//header
if(isset($request->header)) {
foreach($request->header as $k => $v) {
$_SERVER[strtoupper($k)] = $v;
}
}
//get
$_GET = [];
if(isset($request->get)) {
foreach($request->get as $k => $v) {
$_GET[$k] = $v;
}
}
//post
$_POST = [];
if(isset($request->post)) {
foreach($request->post as $k => $v) {
$_POST[$k] = $v;
}
}
//开启缓冲区
ob_start();
// 执行应用并响应
try {
think\Container::get('app', [APP_PATH])
->run()
->send();
}catch (\Exception $e) {
// todo
}
//输出TP当前请求的控制方法
//echo "-action-".request()->action().PHP_EOL;
//获取缓冲区内容
$res = ob_get_contents();
ob_end_clean();
// $response->header("Content-Type","text/html");
$response->header("charset","utf-8");
$response->end($res);
//把之前的进程kill,swoole会重新启一个进程,重启会释放内存,把上一次的资源包括变量等全部清空
//$http->close();
});
//最后启动http服务器
$http->start();
注:以上代码需已安装swoole拓展,将所有代码复制到一个PHP文件即可。
//你以为解决了吗?不,还没有,这时候无论访问的是哪个模块哪个控制器,都直接访问index模块的index控制器的index方法。
此时修改tp5框架源码
修改ThinkPHP5框架Request.php源码位置:/thinkphp/library/think/Request.php
1.function path() { }
//注销判断,不再复用类成员变量$this->path
2.function pathinfo() { }
//注销判断,不再复用类成员变量$this->pathinfo
3.使其支持pathinfo路由,添加如下代码在function pathinfo() { }中
if (isset($_SERVER['PATH_INFO']) && $_SERVER['PATH_INFO'] != '/') {
return ltrim($_SERVER['PATH_INFO'], '/');
}
此时,使用PHP命令行执行前面启动服务的脚本,如 php http.php即可开启端口启动服务。