写点什么

Thinkphp5 集成 Swoole

  • 2022 年 9 月 29 日
    北京
  • 本文字数:2601 字

    阅读完需:约 9 分钟

Swoole 简介

Swoole 是一个面向生产环境的 PHP 异步网络通信引擎。使 PHP 开发人员可以编写高性能的异步并发 TCP、UDP、Unix Socket、HTTP,WebSocket 服务。

Swoole 扩展是按照 PHP 标准扩展构建的。使用 phpize 来生成编译检测脚本,./configure 来做编译配置检测,make 进行编译,make install 进行安装。

Swoole 实际上是一个网络通信和异步 io 的引擎,一个基础库。php 与外部通信需要借助系统的 socket,通常使用的 Apache nginx 就是封装了的 socket,可以实现并发处理。客户端发送请求到 nginx/apache,再转发到 fastcgi 端口交给 php 处理;Swoole 把系统的 socket 集成到 php 底层,php 可以直接通过 swoole 与客户端交互。也就是说 Swoole 是个封装了底层 socket 的网络库,解决异步处理、长连接、并发处理任务等。

Swoole 与传统 php 开发的区别

1.PHP 的运行模式

PHP 有多种运行模式,常见的 Fast-CGI,PHP-FPM 模式我们归纳为传统的 web 模式,还有一种模式属于命令行模式:PHP-Cli

2.Swoole 开发的程序和传统的 php 程序区别

因为使用 swoole 拓展的 PHP 脚本与传统的 PHP 脚步不同,前者是需要预先在服务端执行的,而后者是每次访问时才会执行。

① 比如你的程序中定义了一个类 A,那么在每次有用户访问时,类 A 都需要提前编译到内存中,1 万次访问就要编译 1 万次。而用 swoole 拓展则只需要在服务端编译一次,无论多少次访问都不需要再次编译了,只要 swoole 的进程存在,类 A 就会一直存在于内存中。

② 比如 PHP 入门时就必须要掌握的 session,对于运用了 swoole 扩展的 PHP 程序而言,完全可以用一个变量来替换。

③ 平时写 PHP 代码,完全不必担心内存使用,全局变量/函数/对象等,可以随便使用,因为 PHP 脚本执行结束后,内存自然会自行释放掉。但用 swoole 扩展的 PHP 程序,则必然要手动注销全局的变量/函数/对象等,这就考验了 PHPer 的闭包能力等。

Thinkphp5 集成 Swoole

think-swoole2.0 支持 thinkphp5.0

think-swoole3.0 支持 thinkphp6.0

推出的 tp6.0,已经适配 swoole.并推出 think-swoole 3.0,并且默认适配了 socketio。和 2.0 版本在使用方法上面有些许不同。

Websocket 继承于 Http,进行 websocket 连接之前需要一次 HTTP 请求,如果当期地址支持 websocket 则返回 101,然后进行连接。也就是说并不是我的服务支持 websocket 后,请求每个连接地址都可以进行 websocket 连接,而是需要预先适配才可以连接,tp 提供的组件刚开始不建议使用,等自己写熟悉了后再研究。

01

TP5 的运行机制

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

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

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

02

Swoole 来做 http 服务器

<?php/** * Created by PhpStorm. * User: 360zhiliangxiaoneng * Date: 2019/10/21 * Time: 15:09 */
$http = new swoole_http_server("0.0.0.0", 9501);
$http->set( [ 'enable_static_handler' => true, 'document_root' => "/var/www/thinkphp_5.0.11/public/static", 'worker_num' => 5,//产生进程的个数 ]);
$http->on('WorkerStart',function (swoole_server $server,$worker_id){ define('APP_PATH', __DIR__ . '/../application/'); // 这里 引入 base.php 而不引入start.php 是因为 // start.php 的话 就会执行thinkphp 的相应的控制器方法了 require __DIR__ . '/../thinkphp/base.php';});

$http->on('request', function($request, $response) use($http) { $_SERVER=[];
if(isset($request->header)){ foreach ($request->header as $k=>$v){ $_SERVER[strtoupper($k)] = $v; } } if(isset($request->server)){ foreach ($request->server as $k=>$v){ $_SERVER[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; } } // print_r($_SERVER);
//开启缓存 ob_start(); try{ // 执行应用并响应 //think\Container::get('app', [APP_PATH])->run()->send(); think\App::run()->send(); }catch (\Exception $e){
} $res = ob_get_contents(); ob_end_clean(); $response->header('Content-Type', 'text/html;charset=utf-8', false); $response->end($res); //$http->close();});$http->start();
复制代码
  1. $http->onWorkerStart:启动进程的时候,加载 thinkphp 的框架文件,base.php,但是这个时候,不能 run,等待请求来了再去 run。

  2. $http->onrequest:当收到客户端的请求时,把 Swoole 的 header 头信息,server 信息,get 数据,post 数据等消息转化为常规的 $_SERVER,$_GET 等信息,可以适配 tp5。

  3. 最后开始 run,这个时候需要把 run 得到的信息加载到缓存,然后再通过 send()返回给客户端。

03

Swoole 适配 thinkphp5

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

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



以上总结了 Swoole 是什么、Swoole 与 PHP 开发的区别、Thinkphp5 如何集成 Swoole,希望读者关注公众号交流讨论。

更多学习资料戳下方!!!

https://qrcode.ceba.ceshiren.com/link?name=article&project_id=qrcode&from=infoQ&timestamp=1662366626&author=xueqi

用户头像

社区:ceshiren.com 2022.08.29 加入

微信公众号:霍格沃兹测试开发 提供性能测试、自动化测试、测试开发等资料、实事更新一线互联网大厂测试岗位内推需求,共享测试行业动态及资讯,更可零距离接触众多业内大佬

评论

发布
暂无评论
Thinkphp5 集成 Swoole_测试_测吧(北京)科技有限公司_InfoQ写作社区