请求与响应 #
一、Request对象 #
1.1 获取Request对象 #
php
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class RequestController extends AbstractController
{
#[Route('/request', name: 'app_request')]
public function index(Request $request): Response
{
return new Response('Request received');
}
}
1.2 Request属性 #
php
<?php
class RequestInfoController extends AbstractController
{
#[Route('/request-info', name: 'app_request_info')]
public function info(Request $request): Response
{
$info = [
'method' => $request->getMethod(),
'uri' => $request->getUri(),
'path' => $request->getPathInfo(),
'scheme' => $request->getScheme(),
'host' => $request->getHost(),
'port' => $request->getPort(),
'ip' => $request->getClientIp(),
'userAgent' => $request->headers->get('User-Agent'),
'contentType' => $request->headers->get('Content-Type'),
'isSecure' => $request->isSecure(),
'isAjax' => $request->isXmlHttpRequest(),
];
return $this->json($info);
}
}
二、获取请求参数 #
2.1 查询参数(GET) #
php
<?php
class QueryController extends AbstractController
{
#[Route('/search', name: 'app_search')]
public function search(Request $request): Response
{
$keyword = $request->query->get('keyword', '');
$page = $request->query->getInt('page', 1);
$limit = $request->query->getInt('limit', 10);
$sort = $request->query->get('sort', 'created_at');
return $this->json([
'keyword' => $keyword,
'page' => $page,
'limit' => $limit,
'sort' => $sort,
]);
}
#[Route('/filter', name: 'app_filter')]
public function filter(Request $request): Response
{
$allParams = $request->query->all();
$hasKeyword = $request->query->has('keyword');
$categories = $request->query->all('category');
return $this->json([
'all' => $allParams,
'has_keyword' => $hasKeyword,
'categories' => $categories,
]);
}
}
2.2 表单数据(POST) #
php
<?php
class FormController extends AbstractController
{
#[Route('/form/submit', name: 'app_form_submit', methods: ['POST'])]
public function submit(Request $request): Response
{
$name = $request->request->get('name');
$email = $request->request->get('email');
$message = $request->request->get('message');
return $this->json([
'name' => $name,
'email' => $email,
'message' => $message,
]);
}
#[Route('/form/all', name: 'app_form_all', methods: ['POST'])]
public function allData(Request $request): Response
{
$allData = $request->request->all();
return $this->json($allData);
}
}
2.3 JSON数据 #
php
<?php
class JsonController extends AbstractController
{
#[Route('/api/data', name: 'api_data', methods: ['POST'])]
public function data(Request $request): Response
{
$content = $request->getContent();
$data = json_decode($content, true);
return $this->json([
'received' => $data,
]);
}
#[Route('/api/user', name: 'api_user_create', methods: ['POST'])]
public function createUser(Request $request): Response
{
$data = json_decode($request->getContent(), true);
$name = $data['name'] ?? '';
$email = $data['email'] ?? '';
return $this->json([
'status' => 'created',
'name' => $name,
'email' => $email,
], Response::HTTP_CREATED);
}
}
2.4 文件上传 #
php
<?php
class UploadController extends AbstractController
{
#[Route('/upload', name: 'app_upload', methods: ['POST'])]
public function upload(Request $request): Response
{
$file = $request->files->get('file');
if (!$file) {
return $this->json(['error' => 'No file uploaded'], 400);
}
$originalName = $file->getClientOriginalName();
$mimeType = $file->getMimeType();
$size = $file->getSize();
$extension = $file->getClientOriginalExtension();
$destination = $this->getParameter('kernel.project_dir') . '/public/uploads';
$newFilename = uniqid() . '.' . $extension;
$file->move($destination, $newFilename);
return $this->json([
'original_name' => $originalName,
'mime_type' => $mimeType,
'size' => $size,
'new_filename' => $newFilename,
]);
}
#[Route('/upload/multiple', name: 'app_upload_multiple', methods: ['POST'])]
public function uploadMultiple(Request $request): Response
{
$files = $request->files->all('files');
$uploadedFiles = [];
foreach ($files as $file) {
$originalName = $file->getClientOriginalName();
$newFilename = uniqid() . '.' . $file->getClientOriginalExtension();
$file->move(
$this->getParameter('kernel.project_dir') . '/public/uploads',
$newFilename
);
$uploadedFiles[] = [
'original' => $originalName,
'saved' => $newFilename,
];
}
return $this->json(['files' => $uploadedFiles]);
}
}
三、请求头 #
3.1 获取请求头 #
php
<?php
class HeaderController extends AbstractController
{
#[Route('/headers', name: 'app_headers')]
public function headers(Request $request): Response
{
$contentType = $request->headers->get('Content-Type');
$authorization = $request->headers->get('Authorization');
$userAgent = $request->headers->get('User-Agent');
$accept = $request->headers->get('Accept');
$allHeaders = $request->headers->all();
return $this->json([
'content_type' => $contentType,
'authorization' => $authorization,
'user_agent' => $userAgent,
'accept' => $accept,
]);
}
#[Route('/api/auth', name: 'api_auth')]
public function auth(Request $request): Response
{
$authHeader = $request->headers->get('Authorization');
if (!$authHeader || !str_starts_with($authHeader, 'Bearer ')) {
return $this->json(['error' => 'Unauthorized'], 401);
}
$token = substr($authHeader, 7);
return $this->json([
'token' => $token,
]);
}
}
3.2 常用请求头 #
php
<?php
class CommonHeaderController extends AbstractController
{
#[Route('/common-headers', name: 'app_common_headers')]
public function commonHeaders(Request $request): Response
{
return $this->json([
'host' => $request->headers->get('Host'),
'origin' => $request->headers->get('Origin'),
'referer' => $request->headers->get('Referer'),
'accept_language' => $request->headers->get('Accept-Language'),
'accept_encoding' => $request->headers->get('Accept-Encoding'),
'cache_control' => $request->headers->get('Cache-Control'),
'x_forwarded_for' => $request->headers->get('X-Forwarded-For'),
'x_requested_with' => $request->headers->get('X-Requested-With'),
]);
}
}
四、Cookie和Session #
4.1 Cookie操作 #
php
<?php
use Symfony\Component\HttpFoundation\Cookie;
class CookieController extends AbstractController
{
#[Route('/cookie/get', name: 'app_cookie_get')]
public function getCookie(Request $request): Response
{
$value = $request->cookies->get('my_cookie', 'default');
$allCookies = $request->cookies->all();
return $this->json([
'my_cookie' => $value,
'all' => $allCookies,
]);
}
#[Route('/cookie/set', name: 'app_cookie_set')]
public function setCookie(): Response
{
$response = new Response('Cookie set');
$cookie = Cookie::create('my_cookie')
->withValue('cookie_value')
->withExpires(strtotime('+1 year'))
->withPath('/')
->withDomain('.example.com')
->withSecure(true)
->withHttpOnly(true)
->withSameSite(Cookie::SAMESITE_LAX);
$response->headers->setCookie($cookie);
return $response;
}
#[Route('/cookie/delete', name: 'app_cookie_delete')]
public function deleteCookie(): Response
{
$response = new Response('Cookie deleted');
$response->headers->clearCookie('my_cookie');
return $response;
}
}
4.2 Session操作 #
php
<?php
use Symfony\Component\HttpFoundation\Session\SessionInterface;
class SessionController extends AbstractController
{
#[Route('/session/set', name: 'app_session_set')]
public function setSession(SessionInterface $session): Response
{
$session->set('user_id', 123);
$session->set('username', 'john_doe');
$session->set('cart', ['product_id' => 1, 'quantity' => 2]);
return new Response('Session set');
}
#[Route('/session/get', name: 'app_session_get')]
public function getSession(SessionInterface $session): Response
{
$userId = $session->get('user_id');
$username = $session->get('username', 'guest');
$cart = $session->get('cart', []);
$all = $session->all();
return $this->json([
'user_id' => $userId,
'username' => $username,
'cart' => $cart,
'all' => $all,
]);
}
#[Route('/session/remove', name: 'app_session_remove')]
public function removeSession(SessionInterface $session): Response
{
$session->remove('user_id');
$session->remove('cart');
return new Response('Session removed');
}
#[Route('/session/clear', name: 'app_session_clear')]
public function clearSession(SessionInterface $session): Response
{
$session->clear();
return new Response('Session cleared');
}
#[Route('/session/flash', name: 'app_session_flash')]
public function flashMessage(SessionInterface $session): Response
{
$session->getFlashBag()->add('success', '操作成功!');
$session->getFlashBag()->add('info', '这是一条提示信息');
return $this->redirectToRoute('app_session_show_flash');
}
#[Route('/session/show-flash', name: 'app_session_show_flash')]
public function showFlash(SessionInterface $session): Response
{
$successMessages = $session->getFlashBag()->get('success');
$infoMessages = $session->getFlashBag()->get('info');
return $this->json([
'success' => $successMessages,
'info' => $infoMessages,
]);
}
}
五、Response对象 #
5.1 创建响应 #
php
<?php
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
class ResponseController extends AbstractController
{
#[Route('/response/text', name: 'app_response_text')]
public function text(): Response
{
return new Response('Plain text response');
}
#[Route('/response/html', name: 'app_response_html')]
public function html(): Response
{
$html = '<html><body><h1>HTML Response</h1></body></html>';
return new Response($html);
}
#[Route('/response/json', name: 'app_response_json')]
public function json(): JsonResponse
{
return new JsonResponse([
'status' => 'success',
'data' => ['id' => 1, 'name' => 'John'],
]);
}
#[Route('/response/redirect', name: 'app_response_redirect')]
public function redirect(): RedirectResponse
{
return new RedirectResponse($this->generateUrl('app_home'));
}
}
5.2 响应状态码 #
php
<?php
class StatusCodeController extends AbstractController
{
#[Route('/status/200', name: 'app_status_200')]
public function ok(): Response
{
return new Response('OK', Response::HTTP_OK);
}
#[Route('/status/201', name: 'app_status_201')]
public function created(): Response
{
return new Response('Created', Response::HTTP_CREATED);
}
#[Route('/status/204', name: 'app_status_204')]
public function noContent(): Response
{
return new Response('', Response::HTTP_NO_CONTENT);
}
#[Route('/status/400', name: 'app_status_400')]
public function badRequest(): Response
{
return new Response('Bad Request', Response::HTTP_BAD_REQUEST);
}
#[Route('/status/401', name: 'app_status_401')]
public function unauthorized(): Response
{
return new Response('Unauthorized', Response::HTTP_UNAUTHORIZED);
}
#[Route('/status/403', name: 'app_status_403')]
public function forbidden(): Response
{
return new Response('Forbidden', Response::HTTP_FORBIDDEN);
}
#[Route('/status/404', name: 'app_status_404')]
public function notFound(): Response
{
return new Response('Not Found', Response::HTTP_NOT_FOUND);
}
#[Route('/status/500', name: 'app_status_500')]
public function serverError(): Response
{
return new Response('Internal Server Error', Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
5.3 响应头设置 #
php
<?php
class ResponseHeaderController extends AbstractController
{
#[Route('/header/custom', name: 'app_header_custom')]
public function customHeader(): Response
{
$response = new Response('Custom headers');
$response->headers->set('X-Custom-Header', 'value');
$response->headers->set('X-API-Version', '1.0');
return $response;
}
#[Route('/header/cache', name: 'app_header_cache')]
public function cacheControl(): Response
{
$response = new Response('Cached content');
$response->setPublic();
$response->setMaxAge(3600);
$response->setSharedMaxAge(3600);
$response->setETag('unique-identifier');
return $response;
}
#[Route('/header/no-cache', name: 'app_header_no_cache')]
public function noCache(): Response
{
$response = new Response('No cache content');
$response->headers->addCacheControlDirective('no-cache');
$response->headers->addCacheControlDirective('no-store');
$response->headers->addCacheControlDirective('must-revalidate');
return $response;
}
#[Route('/header/content-type', name: 'app_header_content_type')]
public function contentType(): Response
{
$response = new Response('{"status": "ok"}');
$response->headers->set('Content-Type', 'application/json');
return $response;
}
}
5.4 JSON响应 #
php
<?php
class JsonResponsetController extends AbstractController
{
#[Route('/json/simple', name: 'app_json_simple')]
public function simple(): JsonResponse
{
return $this->json(['message' => 'Hello World']);
}
#[Route('/json/status', name: 'app_json_status')]
public function withStatus(): JsonResponse
{
return $this->json(
['status' => 'created', 'id' => 123],
Response::HTTP_CREATED
);
}
#[Route('/json/headers', name: 'app_json_headers')]
public function withHeaders(): JsonResponse
{
return $this->json(
['data' => 'value'],
Response::HTTP_OK,
[
'X-Custom-Header' => 'value',
'X-API-Version' => '1.0',
]
);
}
#[Route('/json/context', name: 'app_json_context')]
public function withContext(): JsonResponse
{
$data = [
'date' => new \DateTime(),
'user' => new class {
public $name = 'John';
public $email = 'john@example.com';
},
];
return $this->json($data, Response::HTTP_OK, [], [
'json_encode_options' => JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE,
]);
}
}
六、StreamedResponse #
6.1 流式响应 #
php
<?php
use Symfony\Component\HttpFoundation\StreamedResponse;
class StreamController extends AbstractController
{
#[Route('/stream/csv', name: 'app_stream_csv')]
public function csv(): StreamedResponse
{
$response = new StreamedResponse(function () {
$handle = fopen('php://output', 'w');
fputcsv($handle, ['ID', 'Name', 'Email']);
fputcsv($handle, [1, 'John', 'john@example.com']);
fputcsv($handle, [2, 'Jane', 'jane@example.com']);
fputcsv($handle, [3, 'Bob', 'bob@example.com']);
fclose($handle);
});
$response->headers->set('Content-Type', 'text/csv');
$response->headers->set('Content-Disposition', 'attachment; filename="users.csv"');
return $response;
}
#[Route('/stream/large-file', name: 'app_stream_large_file')]
public function largeFile(): StreamedResponse
{
$response = new StreamedResponse(function () {
$handle = fopen($this->getParameter('kernel.project_dir') . '/data/large_file.txt', 'r');
while (!feof($handle)) {
echo fread($handle, 8192);
flush();
}
fclose($handle);
});
$response->headers->set('Content-Type', 'application/octet-stream');
return $response;
}
}
七、BinaryFileResponse #
7.1 文件下载 #
php
<?php
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
class FileController extends AbstractController
{
#[Route('/download/{filename}', name: 'app_download')]
public function download(string $filename): BinaryFileResponse
{
$filepath = $this->getParameter('kernel.project_dir') . '/public/files/' . $filename;
$response = new BinaryFileResponse($filepath);
$response->setContentDisposition(
ResponseHeaderBag::DISPOSITION_ATTACHMENT,
$filename
);
return $response;
}
#[Route('/image/{filename}', name: 'app_image')]
public function image(string $filename): BinaryFileResponse
{
$filepath = $this->getParameter('kernel.project_dir') . '/public/images/' . $filename;
$response = new BinaryFileResponse($filepath);
$response->setContentDisposition(
ResponseHeaderBag::DISPOSITION_INLINE,
$filename
);
return $response;
}
}
八、总结 #
本章学习了:
- Request对象获取和使用
- 获取请求参数(GET/POST/JSON)
- 文件上传处理
- 请求头操作
- Cookie和Session操作
- Response对象创建
- 响应状态码和头设置
- JSON响应
- 流式响应
- 文件下载响应
下一章将学习 控制器高级。
最后更新:2026-03-28