响应

响应实际上是一个support\Response对象,为了方便创建这个对象,webman提供了一些助手函数。

返回一个任意响应

例子

  1. <?php
  2. namespace app\controller;
  3. use support\Request;
  4. class Foo
  5. {
  6. public function hello(Request $request)
  7. {
  8. return response('hello webman');
  9. }
  10. }

response函数实现如下:

  1. function response($body = '', $status = 200, $headers = array())
  2. {
  3. return new Response($status, $headers, $body);
  4. }

你也可以先创建一个空的response对象,然后在适当的位置利用$response->cookie() $response->header() $response->withHeaders() $response->withBody()设置返回内容。

  1. public function hello(Request $request)
  2. {
  3. // 创建一个对象
  4. $response = response();
  5. // .... 业务逻辑省略
  6. // 设置cookie
  7. $response->cookie('foo', 'value');
  8. // .... 业务逻辑省略
  9. // 设置http头
  10. $response->header('Content-Type', 'application/json');
  11. $response->withHeaders([
  12. 'X-Header-One' => 'Header Value 1',
  13. 'X-Header-Tow' => 'Header Value 2',
  14. ]);
  15. // .... 业务逻辑省略
  16. // 设置要返回的数据
  17. $response->withBody('返回的数据');
  18. return $response;
  19. }

返回json

例子

  1. <?php
  2. namespace app\controller;
  3. use support\Request;
  4. class Foo
  5. {
  6. public function hello(Request $request)
  7. {
  8. return json(['code' => 0, 'msg' => 'ok']);
  9. }
  10. }

json函数实现如下

  1. function json($data, $options = JSON_UNESCAPED_UNICODE)
  2. {
  3. return new Response(200, ['Content-Type' => 'application/json'], json_encode($data, $options));
  4. }

返回xml

例子

  1. <?php
  2. namespace app\controller;
  3. use support\Request;
  4. class Foo
  5. {
  6. public function hello(Request $request)
  7. {
  8. $xml = <<<XML
  9. <?xml version='1.0' standalone='yes'?>
  10. <values>
  11. <truevalue>1</truevalue>
  12. <falsevalue>0</falsevalue>
  13. </values>
  14. XML;
  15. return xml($xml);
  16. }
  17. }

xml函数实现如下:

  1. function xml($xml)
  2. {
  3. if ($xml instanceof SimpleXMLElement) {
  4. $xml = $xml->asXML();
  5. }
  6. return new Response(200, ['Content-Type' => 'text/xml'], $xml);
  7. }

返回视图

新建文件 app/controller/Foo.php 如下

  1. <?php
  2. namespace app\controller;
  3. use support\Request;
  4. class Foo
  5. {
  6. public function hello(Request $request)
  7. {
  8. return view('foo/hello', ['name' => 'webman']);
  9. }
  10. }

新建文件 app/view/foo/hello.html 如下

  1. <!doctype html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>webman</title>
  6. </head>
  7. <body>
  8. hello <?=htmlspecialchars($name)?>
  9. </body>
  10. </html>

重定向

  1. <?php
  2. namespace app\controller;
  3. use support\Request;
  4. class Foo
  5. {
  6. public function hello(Request $request)
  7. {
  8. return redirect('/user');
  9. }
  10. }

redirect函数实现如下:

  1. function redirect($location, $status = 302, $headers = [])
  2. {
  3. $response = new Response($status, ['Location' => $location]);
  4. if (!empty($headers)) {
  5. $response->withHeaders($headers);
  6. }
  7. return $response;
  8. }

header设置

  1. <?php
  2. namespace app\controller;
  3. use support\Request;
  4. class Foo
  5. {
  6. public function hello(Request $request)
  7. {
  8. return response('hello webman', 200, [
  9. 'Content-Type' => 'application/json',
  10. 'X-Header-One' => 'Header Value'
  11. ]);
  12. }
  13. }

也可以利用headerwithHeaders方法来单个或者批量设置header。

  1. <?php
  2. namespace app\controller;
  3. use support\Request;
  4. class Foo
  5. {
  6. public function hello(Request $request)
  7. {
  8. return response('hello webman')
  9. ->header('Content-Type', 'application/json')
  10. ->withHeaders([
  11. 'X-Header-One' => 'Header Value 1',
  12. 'X-Header-Tow' => 'Header Value 2',
  13. ]);
  14. }
  15. }

你也可以提前设置header,最后设置将要返回的数据。

  1. public function hello(Request $request)
  2. {
  3. // 创建一个对象
  4. $response = response();
  5. // .... 业务逻辑省略
  6. // 设置http头
  7. $response->header('Content-Type', 'application/json');
  8. $response->withHeaders([
  9. 'X-Header-One' => 'Header Value 1',
  10. 'X-Header-Tow' => 'Header Value 2',
  11. ]);
  12. // .... 业务逻辑省略
  13. // 设置要返回的数据
  14. $response->withBody('返回的数据');
  15. return $response;
  16. }

设置cookie

  1. <?php
  2. namespace app\controller;
  3. use support\Request;
  4. class Foo
  5. {
  6. public function hello(Request $request)
  7. {
  8. return response('hello webman')
  9. ->cookie('foo', 'value');
  10. }
  11. }

你也可以提前设置cookie,最后设置要返回的数据。

  1. public function hello(Request $request)
  2. {
  3. // 创建一个对象
  4. $response = response();
  5. // .... 业务逻辑省略
  6. // 设置cookie
  7. $response->cookie('foo', 'value');
  8. // .... 业务逻辑省略
  9. // 设置要返回的数据
  10. $response->withBody('返回的数据');
  11. return $response;
  12. }

cookie方法完整参数如下:

cookie($name, $value = '', $max_age = 0, $path = '', $domain = '', $secure = false, $http_only = false)

返回文件流

  1. <?php
  2. namespace app\controller;
  3. use support\Request;
  4. class Foo
  5. {
  6. public function hello(Request $request)
  7. {
  8. return response()->file(public_path() . '/favicon.ico');
  9. }
  10. }
  • webman支持发送超大文件
  • 对于大文件(超过2M),webman不会将整个文件一次性读入内存,而是在合适的时机分段读取文件并发送
  • webman会根据客户端接收速度来优化文件读取发送速度,保证最快速发送文件的同时将内存占用减少到最低
  • 数据发送是非阻塞的,不会影响其它请求处理
  • file方法会自动添加if-modified-since头并在下一个请求时检测if-modified-since头,如果文件未修改则直接返回304以便节省带宽
  • 发送的文件会自动使用合适的Content-Type头发送给浏览器
  • 如果文件不存在,会自动转为404响应

下载文件

  1. <?php
  2. namespace app\controller;
  3. use support\Request;
  4. class Foo
  5. {
  6. public function hello(Request $request)
  7. {
  8. return response()->download(public_path() . '/favicon.ico', '可选的文件名.ico');
  9. }
  10. }

download方法与file方法的区别是download方法一般用于下载并保存文件,并且可以设置下载的文件名。download方法不会检查if-modified-since头。其它与file方法行为一致。

获取输出

有些类库是将文件内容直接打印到标准输出的,也就是数据会打印在命令行终端里,并不会发送给浏览器,这时候我们需要通过ob_start(); ob_get_clean(); 将数据捕获到一个变量中,再将数据发送给浏览器,例如:

  1. <?php
  2. namespace app\controller;
  3. use support\Request;
  4. class Image
  5. {
  6. public function get(Request $request)
  7. {
  8. // 创建图像
  9. $im = imagecreatetruecolor(120, 20);
  10. $text_color = imagecolorallocate($im, 233, 14, 91);
  11. imagestring($im, 1, 5, 5, 'A Simple Text String', $text_color);
  12. // 开始获取输出
  13. ob_start();
  14. // 输出图像
  15. imagejpeg($im);
  16. // 获得图像内容
  17. $image = ob_get_clean();
  18. // 发送图像
  19. return response($image)->header('Content-Type', 'image/jpeg');
  20. }
  21. }