StartMVC开发手册

可以快速上手的开发文档

手册目录

Response 响应类

Response 响应类

startmvc\core\Response 是站点的唯一响应出口:状态码、响应头、Cookie、响应体(含文件下载)以及调试追踪面板,全部由它统一发送。控制器既可以 return 一个 Response 对象,也可以直接调用它的方法链。

快速开始

use startmvc\core\Response;

return (new Response())->json(['ok' => true]); // JSON
return (new Response())->text('hello'); // 纯文本
return (new Response())->html('<h1>Hi</h1>'); // HTML
return (new Response())->redirect('/login'); // 302 重定向
return (new Response())->noContent(); // 204 无内容
return (new Response())->download('/data/a.zip'); // 文件下载

send() 外,所有设置类方法都返回 $this,因此可以任意链式组合。

return (new Response())
 ->setStatusCode(201)
 ->setHeader('X-Trace-Id', 'abc123')
 ->cookie('visited', '1', ['expire' => 86400])
 ->json(['created' => true]);

响应类型

  • json($data, $status = 200) —— JSON 响应,响应头 application/json; charset=utf-8,采用 JSON_UNESCAPED_UNICODE 编码,中文不转义。
  • html($content, $status = 200) —— HTML 响应,响应头 text/html; charset=utf-8
  • text($content, $status = 200) —— 纯文本响应,响应头 text/plain; charset=utf-8
  • noContent($status = 204) —— 无响应体的响应,默认 204。
  • setContent($content) —— 直接设置响应体,不改变 Content-Type。

JSON 响应由 json_encode 生成,斜杠会被转义,这是 PHP 的默认行为,属正常输出:

return (new Response())->json(['name' => '张三', 'url' => url('home/index/index')]);
// 输出:{"name":"张三","url":"\/home\/index\/index"}

状态码与响应头

  • setStatusCode($code) —— 设置状态码。
  • setHeader($key, $value) —— 设置单个响应头。
  • setHeaders(array $headers) —— 批量设置响应头,键为头名、值为头值。
  • getStatusCode() —— 读取状态码。
  • getHeader($key) —— 读取指定响应头,键名大小写不敏感,不存在时返回 null
  • getHeaders() —— 读取全部响应头。
  • getContent() —— 读取响应体。
  • getContentType() —— 读取 Content-Type 的媒体类型部分(不含 charset 等参数,统一小写);未设置时返回空串。
  • isSent() —— 本次响应是否已经发送。

重定向

redirect($url, $status = 302) 设置 Location 响应头。$status 可用 301(永久)/ 302(临时)/ 303 / 307 / 308

return (new Response())->redirect('/new-url', 301);

重定向只负责设置响应,不会终止当前方法。需要在设置后立即停止后续逻辑,请自行 return;控制器里的 $this->redirect() 则通过抛出 HttpResponseException 立即中断,详见「重定向与跳转」一节。

文件下载

download($file, $name = null, $mime = null)

  • $file —— 文件真实路径,响应体在发送时以流式读取,不会把大文件读进内存。
  • $name —— 下载时展示的文件名,默认取 basename($file);同时给出 ASCII 回退名与 RFC 5987 的 UTF-8 文件名,中文名在各浏览器下均可正常显示。
  • $mime —— MIME 类型,默认 application/octet-stream

文件不存在或不可读时抛出 RuntimeException(属于调用方错误,快速失败)。

return (new Response())->download(
 ROOT_PATH . 'runtime/export/orders.xlsx',
 '订单导出.xlsx',
 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
);

Cookie

cookie($key, $value, array $options = []) 收集一个待发送的 Cookie。真正的 setcookiesend() 时统一交给 Cookie::set() 完成,因此键名前缀(cookie_prefix)与安全默认值(secure 自动检测、SameSite、HttpOnly)与框架其它地方完全一致。

return (new Response())->html($html)->cookie('visited', '1', ['expire' => 86400]);

$options 支持 expire / path / domain / secure / httponly / samesite,含义同 Cookie::set()

发送响应与调试追踪面板

send() 负责把状态码、响应头、Cookie 与响应体真正发送出去,并附加调试追踪面板。它由框架在请求结束时自动调用,通常不需要手动调用;send() 是幂等的,重复调用只发送一次。

调试追踪面板(trace)的附加规则:

  • 只对 HTML 类页面附加(未声明 Content-Type 时视为 HTML)。
  • JSON、纯文本、文件下载,以及无响应体的 204 / 304 / 3xx 响应一律不附加 —— 往这些响应体里塞 HTML 会直接破坏客户端解析。
  • config/common.phptrace 开关控制,生产环境请关闭。
  • 可用 withTrace(false) / withTrace(true) 显式覆盖自动判定;但无响应体响应与文件下载始终不附加,显式开关也无法覆盖。

完整示例:一个 JSON 接口

use startmvc\core\Controller;
use startmvc\core\Response;

class ApiController extends Controller
{
 public function userAction(int $id = 0)
 {
 $user = $this->getUserById($id); // 由业务方法取得数据

 if (empty($user)) {
 return (new Response())->json(['code' => 0, 'msg' => '用户不存在'], 404);
 }

 return (new Response())->json(['code' => 1, 'data' => $user]);
 }
}

与控制器便捷方法的关系

控制器另提供一组便捷方法,内部同样走 Response,可直接在控制器方法里调用:

  • $this->json($data) —— 输出 JSON 并立即中断执行
  • $this->redirect($url) —— 跳转,同样立即中断执行($url 为空时跳转到 /)。
  • $this->response($code, $msg, $url, $data, $ajax) —— 统一响应入口:Ajax 请求返回 JSON,普通请求渲染跳转页。
  • $this->success($msg, $url, $data, $ajax) / $this->error(...) —— 成功 / 失败的提示与跳转,是 response() 的语法糖(code 分别为 1 与 0)。
  • $this->content($content) —— 以 text/plain 直接输出内容,不终止后续代码。
  • $this->notFound() —— 只设置 404 状态码并发送响应头,既不输出响应体也不终止执行;要终止并渲染 404 页面,请抛出 \Exception('页面不存在', 404)

需要更细的控制(自定义响应头、Cookie、下载文件名等)时,直接 return 一个 Response 对象即可;返回值的各种形态与优先级见「控制器数据输出」一节。