ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、视频、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
[TOC] use Workerman\Protocols\Http\Response; >[danger]注意 >* 除非发送的是chunk或者SSE响应,否则不允许在一个请求里多次发送响应,也就是在一个请求里不允许多次调用`$connection->send()`。 >* 每个请求最终都需要调用一次`$connection->send()`发送响应,否则客户端会一直等待 >* 当不需要更改HTTP状态码(默认200),或者自定义header、cookie时,可以直接向客户端发送字符串完成响应`$connection->send("this is body");` ``` // $file // ::nitMimeTypeMap():void 初始化mime映射 // init() 执行::initMimeTypeMap // __construct($status=200, $headers=[], $body='') // header($name, $value):Response 设置header // withHeader($name, $value):Response 设置header(对header()的二次封装) // withHeaders($headers):Response 批量设置header // withoutHeader($name):Response 移出header // getHeader($name):null|array|string 获取指定header // getHeaders():array 获取所有header // withStatus($code, $reason_phrase = null):Response 设置http响应码 // getStatusCode():int 获取http响应码 // getReasonPhrase():string 获取 reason phrase // withProtocolVersion($version):Response 设置协议版本 // withBody($body):Response 设置http正文 // rawBody():string 获取http原始正文 // withFile($file, $offset = 0, $length = 0):Response 发送文件 // cookie($name, $value = '', $max_age = null, $path = '', $domain = '', $secure = false, $http_only = false, $same_site = ''):Response 设置cookie // __toString() ``` ## 更改状态码 ``` use Workerman\Worker; use Workerman\Connection\TcpConnection; use Workerman\Protocols\Http\Request; use Workerman\Protocols\Http\Response; require_once __DIR__ . '/vendor/autoload.php'; $worker = new Worker('http://0.0.0.0:8080'); $worker->onMessage = function(TcpConnection $connection, Request $request) { if ($request->path() === '/404') { // __construct($status,$headers,$body) $connection->send(new Response(404, [], '<h1>抱歉,文件不存在</h1>')); } else { $connection->send('this is body'); } // 当Response类已经初始化后,想更改状态码使用下面方法 $response = new Response(200); if ($request->path() === '/404') { $response->withStatus(404); $response->withBody('<h1>抱歉,文件不存在</h1>'); $connection->send($response); } else { $connection->send('this is body'); } }; // 运行worker Worker::runAll(); ``` ## 重定向 ``` use Workerman\Worker; use Workerman\Connection\TcpConnection; use Workerman\Protocols\Http\Request; use Workerman\Protocols\Http\Response; require_once __DIR__ . '/vendor/autoload.php'; $worker = new Worker('http://0.0.0.0:8080'); $worker->onMessage = function(TcpConnection $connection, Request $request) $worker = new Worker('http://0.0.0.0:8080'); $worker->onMessage = function($connection, $request) { $location = '/test_location'; $response = new Response(302, ['Location' => $location]); $connection->send($response); }; Worker::runAll(); ``` ## **发送cookie** **例子** ~~~php use Workerman\Worker; use Workerman\Connection\TcpConnection; use Workerman\Protocols\Http\Request; use Workerman\Protocols\Http\Response; require_once __DIR__ . '/vendor/autoload.php'; $worker = new Worker('http://0.0.0.0:8080'); $worker->onMessage = function(TcpConnection $connection, Request $request) { $response = new Response(200, [], 'this is body'); $response->cookie('name', 'tom'); $connection->send($response); }; // 运行worker Worker::runAll(); ~~~ ##发送文件 同样的,发送文件需要使用`Workerman\Protocols\Http\Response`响应类。 发送文件时用以下方式 ~~~php $response = (new Response())->withFile($file); $connection->send($response); ~~~ * workerman支持发送超大文件 * 对于大文件(超过2M),workerman不会将整个文件一次性读入内存,而是在合适的时机分段读取文件并发送 * workerman会根据客户端接收速度来优化文件读取发送速度,保证最快速发送文件的同时将内存占用减少到最低 * 数据发送是非阻塞的,不会影响其它请求处理 * 发送文件时会自动加上`Last-Modified`头,以便下次请求时服务端判断是否发送304响应以节省文件传输提高性能 * 发送的文件会自动使用合适的`Content-Type`头发送给浏览器 * 如果文件不存在,会自动转为404响应 **例子** ~~~php use Workerman\Worker; use Workerman\Connection\TcpConnection; use Workerman\Protocols\Http\Request; use Workerman\Protocols\Http\Response; require_once __DIR__ . '/vendor/autoload.php'; $worker = new Worker('http://0.0.0.0:8080'); $worker->onMessage = function(TcpConnection $connection, Request $request) { $file = '/your/path/of/file'; // 检查if-modified-since头判断文件是否修改过 if (!empty($if_modified_since = $request->header('if-modified-since'))) { $modified_time = date('D, d M Y H:i:s', filemtime($file)) . ' ' . \date_default_timezone_get(); // 文件未修改则返回304 if ($modified_time === $if_modified_since) { $connection->send(new Response(304)); return; } } // 文件修改过或者没有if-modified-since头则发送文件 $response = (new Response())->withFile($file); $connection->send($response); }; // 运行worker Worker::runAll(); ~~~ ## [发送http chunk数据](https://www.workerman.net/doc/workerman/http/response.html#%E5%8F%91%E9%80%81http%20chunk%E6%95%B0%E6%8D%AE) * 必须先发送一个携带`Transfer-Encoding: chunked`头的Response响应给客户端 * 发送后续chunk数据使用`Workerman\Protocols\Http\Chunk`类 * 最终必须发送一个空的chunk来结束响应 **例子** ~~~php use Workerman\Worker; use Workerman\Connection\TcpConnection; use Workerman\Protocols\Http\Request; use Workerman\Protocols\Http\Response; use Workerman\Protocols\Http\Chunk; require_once __DIR__ . '/vendor/autoload.php'; $worker = new Worker('http://0.0.0.0:8080'); $worker->onMessage = function(TcpConnection $connection, Request $request) { // 首先发送一个带Transfer-Encoding: chunked头的Response响应 $connection->send(new Response(200, array('Transfer-Encoding' => 'chunked'), 'hello')); // 后续Chunk数据用Workerman\Protocols\Http\Chunk类发送 $connection->send(new Chunk('第一段数据')); $connection->send(new Chunk('第二段数据')); $connection->send(new Chunk('第三段数据')); // 最后必须发送一个空的chunk结束响应 $connection->send(new Chunk('')); }; // 运行worker Worker::runAll(); ~~~