> For the complete documentation index, see [llms.txt](https://xiaoxiami.gitbook.io/swoole/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://xiaoxiami.gitbook.io/swoole/swoole-ji-chu/wang-luo-tong-xin-yin-qing/chuang-jian-http-fu-wu.md).

# 创建HTTP服务器

建议首选阅读官方文档[Http\Server](https://wiki.swoole.com/wiki/page/326.html)章节

* 一、http\_server简介
* 二、创建http\_server
* 三、swoole\_http\_request
* 四、swoole\_http\_response
* 五、配置介绍（查看官方文档:[配置选项](https://wiki.swoole.com/wiki/page/620.html) ，[常见问题](https://wiki.swoole.com/wiki/page/431.html)）
* 六、nginx+swoole (可查看左侧响应章节)
* 七、多端口监听
* 八、其他： 示例

## 一、http\_server简介

swoole 内置实现了一个简单的httpServer类。swoole版的http server相对于php-fpm，最大优势在于高性能,代码一次载入内存，后续无需再解释执行，但是swoole\_http\_server对Http协议的支持并不完整，实际生产环境，一般是前面加一层Nginx，由Nginx解析一些静态css、js文件，php文件请求交由swoole处理

示意图：

![](/files/-LfnTGVFv76Mt6RJ7GEX)

* 1、http\_server本质是swoole\_server,不过在协议的解析部分固定使用的是http协议解析
* 2、完整的http协议请求会被解析并封装在swoole\_http\_request对象当中
* 3、所有的http响应都通过swoole\_http\_response对象进行封装和发送

## 二、创建http\_server

使用swoole，通过几行代码即可写出一个异步非阻塞多进程的Http服务器

```php
$http=new \swoole\http\server('0.0.0.0',9501);
$http->on('request',function ($request,$response){
    $response->end('发送数给客户端');
});

$http->start();
```

其中onRequest回调接收两个参数分别是swoole\_http\_request对象和swoole\_http\_response对象，分别负责request请求和response响应。

## 三、swoole\_http\_request

swoole\_http\_request，负责http请求的相关信息。我们可以在这个对象上，获取header\server\get\post\files\cookie等信息，这等同于php的超全局变量，但是这可不是超全局的。

```php
$_HEADER = $request->header;
$_SERVER = $request->server;
$_GET =$request->get;
$_POST = $request->post;
$_COOKIE = $request->cookie;
$_FILES = $request->files;
$_CONTENT = request->rawContent;
$request->getData;
```

注意事项：

1、Swoole的HttpServer可以接受application/x-www-form-urlencoded/form-data类型的POST参数，并且会将解析后的参数存放在swoole\_server\_request对象的post成员变量内。

对于application/json或者其他类型的请求参数，Swoole底层并不会自动解析。但是Swoole的swoole\_server\_request提供了rawContent方法可以获得原始的POST字符串,我们可以根据Content-type类型做相应的解析。

2、POST/文件上传需要设置临时文件位置（upload\_tmp\_dir），并且需要设置包的大小，最大尺寸受到 package\_max\_length 配置项限制，默认为2M，调用$response->end后会自动删除，在end之后操作上传文件会抛出文件不存在错误。

## 四、swoole\_http\_response

swoole\_http\_response，负责处理HTTP响应信息，包括响应的头信息header\响应状态等,跟传统的HTTP请求和响应差别不大，比较简单，大概了解下即可。

具体方法如下：

```php
Http\Response->header
Http\Response->cookie
Http\Response->status
Http\Response->gzip
Http\Response->redirect
Http\Response->write
Http\Response->sendfile
Http\Response->end
Http\Response->detach
Http\Response::create
```

> 注意事项：\
> 请在end()之前设置相应的响应头、状态等等，end操作后将向客户端浏览器发送内容，并销毁request/response对象

## 七、多端口监听

在实际运用场景中，服务器可能需要监听不同host下的不同端口。比如，一个应用服务器，可能需要监听外网的服务端口，同时也需要监听内网的管理端口。在Swoole中，可以轻松的实现这样的功能。 Swoole提供了addlistener函数用于给服务器添加一个需要监听的host及port。关于函数的介绍官方文档已经说的比较清楚：[多端口监听的使用](https://wiki.swoole.com/wiki/page/161.html)

示例

server.php

```php
<?php

//创建Server对象，监听 0.0.0.0:9501端口
$serv = new swoole_server("0.0.0.0", 9502,SWOOLE_PROCESS,SWOOLE_SOCK_TCP);

$serv->addlistener('127.0.0.1',9503,SWOOLE_SOCK_TCP);

//配置
$serv->set(array(
    'worker_num' =>5, //设置工作进程
    'reactor_num'=>6, //线程组个数,最大不得超过cpu*4
    'max_request'=>1000,
    'package_max_length '=>1024*1024*3,
//    'open_length_check' => true,
//    'package_length_type'=>'N',
//    'package_length_offset'=>0, //计算总长度
//    'package_body_offset'=>4,//包体位置
//    'package_max_length'=>1024*1024*3 //总的请求数据大小字节为单位
));

//监听连接进入事件,有客户端连接进来的时候会触发
$serv->on('connect', function ($serv,$fd,$from_id) {

});

//监听数据接收事件,server接收到客户端的数据后，worker进程内触发该回调
$serv->on('receive', function ($serv, $fd, $from_id, $data) {

     $info=$serv->connection_info($fd);

     //区分内网外网
     if($info['server_port']){

     }
});
```

注意:

* 1.如果是http协议,不能绑定多个http协议监听
* 2.如果要启用新的协议监听,必须单独调用set方法设置新的协议才会启用新协议
* 3.只有同种协议才会触发相同事件

示例

```php
<?php

//根据端口跟ip地址划分业务,内网外网
$http=new \swoole\http\server('0.0.0.0',9502);

$port1=$http->addlistener('127.0.0.1',9503,SWOOLE_TCP);

//启用新协议
$port1->set([
    'package_max_length'=>1024*1024*10,
]);

$http->set([
    'package_max_length'=>1024*1024*10,
    'upload_tmp_dir'=>__DIR__.'/upload'
]);



//监听http协议
$http->on('request',function ($request,$response){

    var_dump('http');

//$response->end('<meta charset="UTF-8"><h2>呵呵</h2>'); //返回请求

});

//
////为端口1绑定回调
$port1->on('receive',function ($request,$response){

    var_dump('tcp');

//$response->end('<meta charset="UTF-8"><h2>六星教育</h2>'); //返回请求

});

$http->start();
```

## 八、其他示例

```php
<?php
$http=new \swoole\http\server('0.0.0.0',9502);

$http->set([
    'package_max_length'=>1024*1024*10,
    'upload_tmp_dir'=>__DIR__.'/upload'
]);

//监听http协议
$http->on('request',function ($request,$response){

     //var_dump($request->get);
     //var_dump($request->server);

     //var_dump($request->header);
     // $response->end('发送数据给客户端');
     // var_dump('我是post',$request->post);

    //post
     //var_dump($request->rawContent()); //获取原始数据 php://input

    //根据请求头的不同类型,返回相应格式的数据
    if(isset($request->header['content-type']) && $request->header['content-type']=='application/json'){
        var_dump('接收到json格式数据');
         //json_encode();
    }elseif(isset($request->header['content-type']) && $request->header['content-type']=='application/xml'){

    }

    //文件上传
    //$file=$request->files;
   //move_uploaded_file($file['peterFile']['tmp_name'],__DIR__.'/upload/1.txt');
    //设置响应头
//    $response->header('Content-Type','text/html');
//    $response->header('Charset','utf-8');
//
//    $response->status(123);
//
//    $response->cookie('user','peter');
//
//    $response->write('123---'); //分段发送不能使用end
//    $response->write('456'); //分段发送不能使用end
//
//    $response->end('<meta charset="UTF-8"><h2>六星教育</h2>'); //返回请求
    //$response->header('Content-Type', 'image/jpeg');
    //$response->sendfile(__DIR__.'/upload/1.txt');


});

$http->start();
```
