You are browsing the documentation for Symfony 2.2 which is not maintained anymore.
Consider upgrading your projects to Symfony 5.2.
The HttpFoundation Component
The HttpFoundation Component¶
The HttpFoundation component defines an object-oriented layer for the HTTP specification.
In PHP, the request is represented by some global variables ($_GET
,
$_POST
, $_FILES
, $_COOKIE
, $_SESSION
, …) and the response is
generated by some functions (echo
, header
, setcookie
, …).
The Symfony2 HttpFoundation component replaces these default PHP global variables and functions by an object-oriented layer.
Installation¶
You can install the component in 2 different ways:
- Install it via Composer (
symfony/http-foundation
on Packagist); - Use the official Git repository (https://github.com/symfony/HttpFoundation).
Request¶
The most common way to create a request is to base it on the current PHP global
variables with
createFromGlobals()
:
use Symfony\Component\HttpFoundation\Request;
$request = Request::createFromGlobals();
which is almost equivalent to the more verbose, but also more flexible,
__construct()
call:
$request = new Request(
$_GET,
$_POST,
array(),
$_COOKIE,
$_FILES,
$_SERVER
);
Accessing Request Data¶
A Request object holds information about the client request. This information can be accessed via several public properties:
request
: equivalent of$_POST
;query
: equivalent of$_GET
($request->query->get('name')
);cookies
: equivalent of$_COOKIE
;attributes
: no equivalent - used by your app to store other data (see below);files
: equivalent of$_FILES
;server
: equivalent of$_SERVER
;headers
: mostly equivalent to a sub-set of$_SERVER
($request->headers->get('User-Agent')
).
Each property is a Symfony\Component\HttpFoundation\ParameterBag
instance (or a sub-class of), which is a data holder class:
request
:Symfony\Component\HttpFoundation\ParameterBag
;query
:Symfony\Component\HttpFoundation\ParameterBag
;cookies
:Symfony\Component\HttpFoundation\ParameterBag
;attributes
:Symfony\Component\HttpFoundation\ParameterBag
;files
:Symfony\Component\HttpFoundation\FileBag
;server
:Symfony\Component\HttpFoundation\ServerBag
;headers
:Symfony\Component\HttpFoundation\HeaderBag
.
All Symfony\Component\HttpFoundation\ParameterBag
instances have
methods to retrieve and update its data:
all()
: Returns the parameters;keys()
: Returns the parameter keys;replace()
: Replaces the current parameters by a new set;add()
: Adds parameters;get()
: Returns a parameter by name;set()
: Sets a parameter by name;has()
: Returnstrue
if the parameter is defined;remove()
: Removes a parameter.
The Symfony\Component\HttpFoundation\ParameterBag
instance also
has some methods to filter the input values:
getAlpha()
: Returns the alphabetic characters of the parameter value;getAlnum()
: Returns the alphabetic characters and digits of the parameter value;getDigits()
: Returns the digits of the parameter value;getInt()
: Returns the parameter value converted to integer;filter()
: Filters the parameter by using the PHPfilter_var
function.
All getters takes up to three arguments: the first one is the parameter name and the second one is the default value to return if the parameter does not exist:
// the query string is '?foo=bar'
$request->query->get('foo');
// returns bar
$request->query->get('bar');
// returns null
$request->query->get('bar', 'bar');
// returns 'bar'
When PHP imports the request query, it handles request parameters like
foo[bar]=bar
in a special way as it creates an array. So you can get the
foo
parameter and you will get back an array with a bar
element. But
sometimes, you might want to get the value for the “original” parameter name:
foo[bar]
. This is possible with all the ParameterBag
getters like
get()
via the third
argument:
// the query string is '?foo[bar]=bar'
$request->query->get('foo');
// returns array('bar' => 'bar')
$request->query->get('foo[bar]');
// returns null
$request->query->get('foo[bar]', null, true);
// returns 'bar'
Finally, you can also store additional data in the request,
thanks to the public attributes
property, which is also an instance of
Symfony\Component\HttpFoundation\ParameterBag
. This is mostly used
to attach information that belongs to the Request and that needs to be
accessed from many different points in your application. For information
on how this is used in the Symfony2 framework, see
the Symfony2 book.
Identifying a Request¶
In your application, you need a way to identify a request; most of the time,
this is done via the “path info” of the request, which can be accessed via the
getPathInfo()
method:
// for a request to http://example.com/blog/index.php/post/hello-world
// the path info is "/post/hello-world"
$request->getPathInfo();
Simulating a Request¶
Instead of creating a request based on the PHP globals, you can also simulate a request:
$request = Request::create(
'/hello-world',
'GET',
array('name' => 'Fabien')
);
The create()
method
creates a request based on a URI, a method and some parameters (the
query parameters or the request ones depending on the HTTP method); and of
course, you can also override all other variables as well (by default, Symfony
creates sensible defaults for all the PHP global variables).
Based on such a request, you can override the PHP global variables via
overrideGlobals()
:
$request->overrideGlobals();
Tip
You can also duplicate an existing request via
duplicate()
or
change a bunch of parameters with a single call to
initialize()
.
Accessing the Session¶
If you have a session attached to the request, you can access it via the
getSession()
method;
the
hasPreviousSession()
method tells you if the request contains a session which was started in one of
the previous requests.
Accessing Accept-* Headers Data¶
You can easily access basic data extracted from Accept-*
headers
by using the following methods:
getAcceptableContentTypes()
: returns the list of accepted content types ordered by descending quality;getLanguages()
: returns the list of accepted languages ordered by descending quality;getCharsets()
: returns the list of accepted charsets ordered by descending quality.
New in version 2.2: The Symfony\Component\HttpFoundation\AcceptHeader
class is new in Symfony 2.2.
If you need to get full access to parsed data from Accept
, Accept-Language
,
Accept-Charset
or Accept-Encoding
, you can use
Symfony\Component\HttpFoundation\AcceptHeader
utility class:
use Symfony\Component\HttpFoundation\AcceptHeader;
$accept = AcceptHeader::fromString($request->headers->get('Accept'));
if ($accept->has('text/html')) {
$item = $accept->get('text/html');
$charset = $item->getAttribute('charset', 'utf-8');
$quality = $item->getQuality();
}
// accepts items are sorted by descending quality
$accepts = AcceptHeader::fromString($request->headers->get('Accept'))->all();
Accessing other Data¶
The Request
class has many other methods that you can use to access the
request information. Have a look at
the Request API
for more information about them.
Response¶
A Symfony\Component\HttpFoundation\Response
object holds all the
information that needs to be sent back to the client from a given request. The
constructor takes up to three arguments: the response content, the status
code, and an array of HTTP headers:
use Symfony\Component\HttpFoundation\Response;
$response = new Response(
'Content',
200,
array('content-type' => 'text/html')
);
These information can also be manipulated after the Response object creation:
$response->setContent('Hello World');
// the headers public attribute is a ResponseHeaderBag
$response->headers->set('Content-Type', 'text/plain');
$response->setStatusCode(404);
When setting the Content-Type
of the Response, you can set the charset,
but it is better to set it via the
setCharset()
method:
$response->setCharset('ISO-8859-1');
Note that by default, Symfony assumes that your Responses are encoded in UTF-8.
Sending the Response¶
Before sending the Response, you can ensure that it is compliant with the HTTP
specification by calling the
prepare()
method:
$response->prepare($request);
Sending the response to the client is then as simple as calling
send()
:
$response->send();
Setting Cookies¶
The response cookies can be manipulated through the headers
public
attribute:
use Symfony\Component\HttpFoundation\Cookie;
$response->headers->setCookie(new Cookie('foo', 'bar'));
The
setCookie()
method takes an instance of
Symfony\Component\HttpFoundation\Cookie
as an argument.
You can clear a cookie via the
clearCookie()
method.
Managing the HTTP Cache¶
The Symfony\Component\HttpFoundation\Response
class has a rich set
of methods to manipulate the HTTP headers related to the cache:
setPublic()
;setPrivate()
;expire()
;setExpires()
;setMaxAge()
;setSharedMaxAge()
;setTtl()
;setClientTtl()
;setLastModified()
;setEtag()
;setVary()
;
The setCache()
method
can be used to set the most commonly used cache information in one method
call:
$response->setCache(array(
'etag' => 'abcdef',
'last_modified' => new \DateTime(),
'max_age' => 600,
's_maxage' => 600,
'private' => false,
'public' => true,
));
To check if the Response validators (ETag
, Last-Modified
) match a
conditional value specified in the client Request, use the
isNotModified()
method:
if ($response->isNotModified($request)) {
$response->send();
}
If the Response is not modified, it sets the status code to 304 and remove the actual response content.
Redirecting the User¶
To redirect the client to another URL, you can use the
Symfony\Component\HttpFoundation\RedirectResponse
class:
use Symfony\Component\HttpFoundation\RedirectResponse;
$response = new RedirectResponse('http://example.com/');
Streaming a Response¶
New in version 2.1: Support for streamed responses was added in Symfony 2.1.
The Symfony\Component\HttpFoundation\StreamedResponse
class allows
you to stream the Response back to the client. The response content is
represented by a PHP callable instead of a string:
use Symfony\Component\HttpFoundation\StreamedResponse;
$response = new StreamedResponse();
$response->setCallback(function () {
echo 'Hello World';
flush();
sleep(2);
echo 'Hello World';
flush();
});
$response->send();
Note
The flush()
function does not flush buffering. If ob_start()
has
been called before or the output_buffering
php.ini
option is enabled,
you must call ob_flush()
before flush()
.
Additionally, PHP isn’t the only layer that can buffer output. Your web server might also buffer based on its configuration. Even more, if you use fastcgi, buffering can’t be disabled at all.
Serving Files¶
New in version 2.1: The makeDisposition
method was added in Symfony 2.1.
When sending a file, you must add a Content-Disposition
header to your
response. While creating this header for basic file downloads is easy, using
non-ASCII filenames is more involving. The
makeDisposition()
abstracts the hard work behind a simple API:
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
$d = $response->headers->makeDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, 'foo.pdf');
$response->headers->set('Content-Disposition', $d);
New in version 2.2: The Symfony\Component\HttpFoundation\BinaryFileResponse
class was added in Symfony 2.2.
Alternatively, if you are serving a static file, you can use a
Symfony\Component\HttpFoundation\BinaryFileResponse
:
use Symfony\Component\HttpFoundation\BinaryFileResponse;
$file = 'path/to/file.txt';
$response = new BinaryFileResponse($file);
The BinaryFileResponse
will automatically handle Range
and
If-Range
headers from the request. It also supports X-Sendfile
(see for Nginx and Apache). To make use of it, you need to determine
whether or not the X-Sendfile-Type
header should be trusted and call
trustXSendfileTypeHeader()
if it should:
BinaryFileResponse::trustXSendfileTypeHeader();
You can still set the Content-Type
of the sent file, or change its Content-Disposition
:
$response->headers->set('Content-Type', 'text/plain');
$response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, 'filename.txt');
Creating a JSON Response¶
Any type of response can be created via the
Symfony\Component\HttpFoundation\Response
class by setting the
right content and headers. A JSON response might look like this:
use Symfony\Component\HttpFoundation\Response;
$response = new Response();
$response->setContent(json_encode(array(
'data' => 123,
)));
$response->headers->set('Content-Type', 'application/json');
New in version 2.1: The Symfony\Component\HttpFoundation\JsonResponse
class was added in Symfony 2.1.
There is also a helpful Symfony\Component\HttpFoundation\JsonResponse
class, which can make this even easier:
use Symfony\Component\HttpFoundation\JsonResponse;
$response = new JsonResponse();
$response->setData(array(
'data' => 123
));
This encodes your array of data to JSON and sets the Content-Type
header
to application/json
.
Caution
To avoid XSSI JSON Hijacking, you should pass an associative array
as the outer-most array to JsonResponse
and not an indexed array so
that the final result is an object (e.g. {"object": "not inside an array"}
)
instead of an array (e.g. [{"object": "inside an array"}]
). Read
the OWASP guidelines for more information.
Only methods that respond to GET requests are vulnerable to XSSI ‘JSON Hijacking’. Methods responding to POST requests only remain unaffected.
JSONP Callback¶
If you’re using JSONP, you can set the callback function that the data should be passed to:
$response->setCallback('handleResponse');
In this case, the Content-Type
header will be text/javascript
and
the response content will look like this:
1 | handleResponse({'data': 123});
|
Session¶
The session information is in its own document: Session Management.
This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.