Swoole完美支持ThinkPHP5

Swoole完美支持ThinkPHP5

一、首先要开启http的server

  1. 能够在thinkphp的目录下建立一个server目录,里面建立一个HTTPServer的php

二、须要在WorkerStart回调事件作两件事

  1. 定义应用目录:define('APP_PATH', __DIR__ . '/../application/');
  2. 加载基础文件:require __DIR__ . '/../thinkphp/base.php';

三、由于swoole接收get、post参数等和thinkphp中接收不同,因此须要转换为thinkphp可识别,转换get参数示例以下:

注意点: swoole对于超全局数组: $_SERVER$_GET$_POSTdefine定义的常量等不会释放,因此须要先清空一次
// 先清空
$_GET = [];
if (isset($request->get)) {
    foreach ($request->get as $key => $value) {
        $_GET[$key] = $value;
    }
}

四、thinkphp会把模块、控制器、方法放到一个变量里去,因此经过pathinfo模式访问会存在只能访问第一次的pathinfo这个问题,worker进程里是不会注销变量的

解决办法:
thinkphp/library/think/Request.php
function path 中的 if (is_null($this->path)) {}注释或删除
function pathinfo中的 if (is_null($this->pathinfo)) {}注释或删除
注意:只删除条件,不删除条件中的内容

五、swoole支持thinkphp的http_server示例:

// 面向过程写法

$http = new swoole_http_server('0.0.0.0', 9501);

$http->set([
    // 开启静态资源请求
    'enable_static_handler' => true,
    'document_root' => '/opt/app/live/public/static',
    'worker_num' => 5,
]);

/**
 * WorkerStart事件在Worker进程/Task进程启动时发生。这里建立的对象能够在进程生命周期内使用
 * 目的:加载thinkphp框架中的内容
 */
$http->on('WorkerStart', function (swoole_server $server, $worker_id) {
    // 定义应用目录
    define('APP_PATH', __DIR__ . '/../application/');
    // 加载基础文件
    require __DIR__ . '/../thinkphp/base.php';
});

$http->on('request', function ($request, $response) {

    // 把swoole接收的信息转换为thinkphp可识别的
    $_SERVER = [];
    if (isset($request->server)) {
        foreach ($request->server as $key => $value) {
            $_SERVER[strtoupper($key)] = $value;
        }
    }

    if (isset($request->header)) {
        foreach ($request->header as $key => $value) {
            $_SERVER[strtoupper($key)] = $value;
        }
    }

    // swoole对于超全局数组:$_SERVER、$_GET、$_POST、define不会释放
    $_GET = [];
    if (isset($request->get)) {
        foreach ($request->get as $key => $value) {
            $_GET[$key] = $value;
        }
    }

    $_POST = [];
    if (isset($request->post)) {
        foreach ($request->post as $key => $value) {
            $_POST[$key] = $value;
        }
    }

    // ob函数输出打印
    ob_start();
    try {
        think\Container::get('app', [APP_PATH]) ->run() ->send();
        $res = ob_get_contents();
        ob_end_clean();
    } catch (\Exception $e) {
        // todo
    }

    $response->end($res);
});

$http->start();
相关文章
相关标签/搜索