TP5的运行机制
任何请求都会经过tp5的入口文件,载入框架的配置文件,启动进程,然后处理请求。

swoole4.0 支持thinkhphp5.1_服务器

在这个index.php的入口文件中,可以看到,它先定义的APP_PATH这个常量,然后引入的框架的启动文件start.php,那我们就去看下start.php这个文件做了些什么。

swoole4.0 支持thinkhphp5.1_服务器_02

在这里,它先加载了基础文件base.php,然后启动框架run,这个时候就开始处理请求了。
常规的nginx,Apache服务器,每次请求来到thinkphp,会清除静态变量,重新加载配置文件。但是,swoole做的服务器,是常驻进程,在启动服务后,会产生多个进程,来处理请求。我们要让它选择性的加载配置。Swoole来做http服务器

<?php

$http = new swoole_http_server("0.0.0.0", 8811);

$http->set(
[
'enable_static_handler' => true,
'document_root' => "/www/wwwroot/swoole_tp5/public/static",
'worker_num' => 5,
]
);
$http->on("WorkerStart",function ( $ser,$worker_id){
// 定义应用目录
define('APP_PATH', __DIR__ . '/../application/');
// ThinkPHP 引导文件
// 1. 加载基础文件
require __DIR__ . '/../thinkphp/base.php';
// 加载框架引导文件
// require __DIR__ . '/../thinkphp/start.php';
});
$http->on('request', function($request, $response) use($http) {
if(isset($request->header)){
foreach ($request->header as $k=>$v){
$_SERVER[strtoupper($k)] = $v;
}
}
if(isset($request->server)){
foreach ($request->server as $k=>$v){
$_HEADER[strtoupper($k)] = $v;
}
}
$_GET = [];
if(isset($request->get)){
foreach ($request->get as $k=>$v){
$_GET[$k] = $v;
}
}
$_POST = [];
if(isset($request->post)){
foreach ($request->post as $k=>$v){
$_POST[$k] = $v;
}
}

ob_start();
//执行应用并相应
try{
// thinkphp 执行应用并响应
think\Container::get('app')
->run()
->send();
}catch (\Exception $exception){
// todo
}
$res = ob_get_contents();
if (ob_get_length()) ob_end_clean();
$response->end($res);
// $http->close();
});
$http->start();

// topthink/think-swoole

index控制器

<?php
namespace app\index\controller;
class Index
{
public function index()
{
print_r($_GET);
echo 'dddd';
}

public function dahai() {
echo time();
}

public function hello($name = 'ThinkPHP5')
{
echo 'hessdggsg' . $name.time();
}

}

代码说明:
(1)$http->onWorkerStart:启动进程的时候,加载thinkphp的框架文件,base.php,但是这个时候,不能run,等待请求来了再去run。
(2)$http->onrequest:当收到客户端的请求时,把swoole的header头信息,server信息,get数据,post数据等消息转化为常规的$_SERVER,$_GET等信息,可以适配tp5。
(3)最后开始run,这个时候需要把run得到的信息加载到缓存,然后再通过send()返回给客户端。

Swoole适配thinkphp5
因为swoole是常驻进程,前一个请求的$_POST,$_GET请求不会销毁,原因这个进程并没有kill,这个时候,需要在接收请求的时候,将$_GET,$_POST置空。
swoole路由机制,总会从缓存中获取有没有这个请求,如果有,就不加载新的,所以,swoole常驻内存,会发现一直请求第一个url。除非重启swoole服务器。

swoole4.0 支持thinkhphp5.1_服务器_03

在thinkphp框架里面,修改Request文件,将两个方法(pathinfo,path)里面的$this->path这个为空的判断去掉,让每次请求都去解析这个url。
验证结果

swoole4.0 支持thinkhphp5.1_服务器_04

swoole4.0 支持thinkhphp5.1_php_05