(备注:这只是 swoole 和 TP5 结合的始端,想必二者的深入融合会有更多的坑需要踩!)
首先去 TP 官网下载框架
总体概览图:
在项目根目录下新建 server 文件夹,
http_server.php 内容如下(可以直接拷贝过去使用):
<?php
/**
* Created by PhpStorm.
* User: baidu
* Date: 18/2/28
* Time: 上午1:39
*/
$http = new swoole_http_server("0.0.0.0", 8811);
$http->set(
[
'enable_static_handler' => true,
'document_root' => "/home/work/swoole/thinkphpcore/public",
'worker_num' => 5,
'content-type' => 'text/html; charset=utf-8',
]
);
$http->on('WorkerStart', function (swoole_server $server, $worker_id) {
// 定义应用目录
define('APP_PATH', __DIR__ . '/../application/');
// 1. 加载基础文件
require __DIR__ . '/../thinkphpcore/base.php';
// 这里不能使用这种方式加载框架内容,不信你可以打开试试
// require __DIR__ . '/../thinkphpcore/start.php';
});
$http->on('request', function($request, $response) use ($http) {
//print_r($request->get);
$content = [
'date:' => date("Ymd H:i:s"),
'get:' => $request->get,
'post:' => $request->post,
'header:' => $request->header,
];
swoole_async_writefile(__DIR__."/access.log", json_encode($content).PHP_EOL, function($filename) {
// todo
}, FILE_APPEND);
$_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) {
$_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;
}
}
// 2. 执行应用
ob_start();
try {
think\App::run()->send();
} catch (Exception $e) {
echo $e->getMessage();
}
$res = ob_get_contents();
ob_end_clean();
$response->end($res);
// 这是种简单粗暴的销毁进程、重新加载框架内容的方式
// $http->close($request);
});
$http->start();
一:开启 URL 普通模式
找到 thinkphp5-thinkphpcore-library-think-Request.php 的 pathinfo() 和 path() 方法
把这两处的 if (is_null) 判断语句注释掉.
因为如果不注释变量 pathinfo 只会存储框架第一次运行保存下来的值.
/**
* 获取当前请求URL的pathinfo信息(含URL后缀)
* @access public
* @return string
*/
public function pathinfo()
{
// if (is_null($this->pathinfo)) {
...
...
...
// }
return $this->pathinfo;
}
/**
* 获取当前请求URL的pathinfo信息(不含URL后缀)
* @access public
* @return string
*/
public function path()
{
// if (is_null($this->path)) {
...
...
...
// }
return $this->path;
}
效果访问如下:
二:开启 pathinfo 模式:
/**
* 获取当前请求URL的pathinfo信息(含URL后缀)
* @access public
* @return string
*/
public function pathinfo()
{
// 配置 pathinfo
if (isset($_SERVER['PATH_INFO']) && $_SERVER['PATH_INFO'] != '/') {
return ltrim($_SERVER['PATH_INFO'], '/');
}
// 配置 普通访问模式
// if (is_null($this->pathinfo)) {
...
...
...
// }
return $this->pathinfo;
}
/**
* 获取当前请求URL的pathinfo信息(不含URL后缀)
* @access public
* @return string
*/
public function path()
{
// if (is_null($this->path)) {
...
...
...
// }
return $this->path;
}
访问效果如下:
Index.php 示例代码:
<?php
namespace app\index\controller;
use think\request;
class Index
{
public function index(Request $request)
{
return 'hello-swoole';
}
public function check()
{
print_r($_GET);
return time();
}
public function getClientIp()
{
$list = swoole_get_local_ip();
print_r($list);
}
}
- swoole_http_server对Http协议的支持并不完整,建议仅作为应用服务器。并且在前端增加Nginx作为代理
-
swoole-1.7.7增加了内置Http服务器的支持,通过几行代码即可写出一个异步非阻塞多进程的Http服务器。
$http = new swoole_http_server("127.0.0.1", 9501); $http->on('request', function ($request, $response) { $response->end("<h1>Hello Swoole. #".rand(1000, 9999)."</h1>"); }); $http->start();
通过使用apache bench工具进行压力测试,在Inter Core-I5 4核 + 8G内存的普通PC机器上,swoole_http_server可以达到近11万QPS。远远超过php-fpm,golang自带http服务器,node.js自带http服务器。性能几乎接近与Nginx的静态文件处理。
ab -c 200 -n 200000 -k http://127.0.0.1:9501
转载于:https://blog.51cto.com/laok8/2314816