Skip to content

Commit

Permalink
Merge branch '2.8'
Browse files Browse the repository at this point in the history
* 2.8:
  [#5098] Minor fix so controller in dumped apache matches _controller route information above
  fix code block order
  Update process.rst
  [Cookbook] Add warning about Composer dev deps on Heroku
  Added a note against using the Apache Router
  Implemented all the changes suggested by reviewers
  Minor rewording
  Reviewed Configuration cookbook articles
  Reviewed Cache cookbook articles
  • Loading branch information
weaverryan committed Apr 15, 2015
2 parents c4e07cc + 721ed95 commit 2e86186
Show file tree
Hide file tree
Showing 57 changed files with 734 additions and 685 deletions.
22 changes: 11 additions & 11 deletions book/forms.rst
Expand Up @@ -344,17 +344,6 @@ object.

.. configuration-block::

.. code-block:: yaml
# AppBundle/Resources/config/validation.yml
AppBundle\Entity\Task:
properties:
task:
- NotBlank: ~
dueDate:
- NotBlank: ~
- Type: \DateTime
.. code-block:: php-annotations
// AppBundle/Entity/Task.php
Expand All @@ -374,6 +363,17 @@ object.
protected $dueDate;
}
.. code-block:: yaml
# AppBundle/Resources/config/validation.yml
AppBundle\Entity\Task:
properties:
task:
- NotBlank: ~
dueDate:
- NotBlank: ~
- Type: \DateTime
.. code-block:: xml
<!-- AppBundle/Resources/config/validation.xml -->
Expand Down
2 changes: 1 addition & 1 deletion components/process.rst
Expand Up @@ -36,7 +36,7 @@ a command in a sub-process::
The component takes care of the subtle differences between the different platforms
when executing the command.

The ``getOutput()`` method always return the whole content of the standard
The ``getOutput()`` method always returns the whole content of the standard
output of the command and ``getErrorOutput()`` the content of the error
output. Alternatively, the :method:`Symfony\\Component\\Process\\Process::getIncrementalOutput`
and :method:`Symfony\\Component\\Process\\Process::getIncrementalErrorOutput`
Expand Down
2 changes: 1 addition & 1 deletion cookbook/cache/form_csrf_caching.rst
Expand Up @@ -22,7 +22,7 @@ validation when submitting the form.

In fact, many reverse proxies (like Varnish) will refuse to cache a page
with a CSRF token. This is because a cookie is sent in order to preserve
the PHP session open and Varnish's default behaviour is to not cache HTTP
the PHP session open and Varnish's default behavior is to not cache HTTP
requests with cookies.

How to Cache Most of the Page and still be able to Use CSRF Protection
Expand Down
68 changes: 30 additions & 38 deletions cookbook/cache/varnish.rst
Expand Up @@ -15,25 +15,31 @@ cached content fast and including support for :ref:`Edge Side Includes <edge-sid
Make Symfony Trust the Reverse Proxy
------------------------------------

For ESI to work correctly and for the :ref:`X-FORWARDED <varnish-x-forwarded-headers>`
headers to be used, you need to configure Varnish as a
:doc:`trusted proxy </cookbook/request/load_balancer_reverse_proxy>`.
Varnish automatically forwards the IP as ``X-Forwarded-For`` and leaves the
``X-Forwarded-Proto`` header in the request. If you do not configure Varnish as
trusted proxy, Symfony will see all requests as coming through insecure HTTP
connections from the Varnish host instead of the real client.

Remember to configure :ref:`framework.trusted_proxies <reference-framework-trusted-proxies>`
in the Symfony configuration so that Varnish is seen as a trusted proxy and the
:ref:`X-Forwarded <varnish-x-forwarded-headers>` headers are used.

.. _varnish-x-forwarded-headers:

Routing and X-FORWARDED Headers
-------------------------------

To ensure that the Symfony Router generates URLs correctly with Varnish,
a ``X-Forwarded-Port`` header must be present for Symfony to use the
correct port number.
If the ``X-Forwarded-Port`` header is not set correctly, Symfony will append
the port where the PHP application is running when generating absolute URLs,
e.g. ``http://example.com:8080/my/path``. To ensure that the Symfony router
generates URLs correctly with Varnish, add the correct port number in the
``X-Forwarded-Port`` header. This port depends on your setup.

This port depends on your setup. Lets say that external connections come in
on the default HTTP port 80. For HTTPS connections, there is another proxy
(as Varnish does not do HTTPS itself) on the default HTTPS port 443 that
handles the SSL termination and forwards the requests as HTTP requests to
Varnish with a ``X-Forwarded-Proto`` header. In this case, you need to add
the following configuration snippet:
Suppose that external connections come in on the default HTTP port 80. For HTTPS
connections, there is another proxy (as Varnish does not do HTTPS itself) on the
default HTTPS port 443 that handles the SSL termination and forwards the requests
as HTTP requests to Varnish with a ``X-Forwarded-Proto`` header. In this case,
add the following to your Varnish configuration:

.. code-block:: varnish4
Expand All @@ -45,45 +51,30 @@ the following configuration snippet:
}
}
.. note::

Remember to configure :ref:`framework.trusted_proxies <reference-framework-trusted-proxies>`
in the Symfony configuration so that Varnish is seen as a trusted proxy
and the ``X-Forwarded-*`` headers are used.

Varnish automatically forwards the IP as ``X-Forwarded-For`` and leaves
the ``X-Forwarded-Proto`` header in the request. If you do not configure
Varnish as trusted proxy, Symfony will see all requests as coming through
insecure HTTP connections from the Varnish host instead of the real client.

If the ``X-Forwarded-Port`` header is not set correctly, Symfony will append
the port where the PHP application is running when generating absolute URLs,
e.g. ``http://example.com:8080/my/path``.

Cookies and Caching
-------------------

By default, a sane caching proxy does not cache anything when a request is sent
with :ref:`cookies or a basic authentication header<http-cache-introduction>`.
with :ref:`cookies or a basic authentication header <http-cache-introduction>`.
This is because the content of the page is supposed to depend on the cookie
value or authentication header.

If you know for sure that the backend never uses sessions or basic
authentication, have varnish remove the corresponding header from requests to
authentication, have Varnish remove the corresponding header from requests to
prevent clients from bypassing the cache. In practice, you will need sessions
at least for some parts of the site, e.g. when using forms with
:ref:`CSRF Protection <forms-csrf>`. In this situation, make sure to
:doc:`only start a session when actually needed </cookbook/session/avoid_session_start>`
and clear the session when it is no longer needed. Alternatively, you can look
into :doc:`/cookbook/cache/form_csrf_caching`.

Cookies created in Javascript and used only in the frontend, e.g. when using
Google analytics are nonetheless sent to the server. These cookies are not
Cookies created in JavaScript and used only in the frontend, e.g. when using
Google Analytics, are nonetheless sent to the server. These cookies are not
relevant for the backend and should not affect the caching decision. Configure
your Varnish cache to `clean the cookies header`_. You want to keep the
session cookie, if there is one, and get rid of all other cookies so that pages
are cached if there is no active session. Unless you changed the default
configuration of PHP, your session cookie has the name PHPSESSID:
configuration of PHP, your session cookie has the name ``PHPSESSID``:

.. code-block:: varnish4
Expand All @@ -110,8 +101,8 @@ configuration of PHP, your session cookie has the name PHPSESSID:
implemented and explained by the FOSHttpCacheBundle_ under the name
`User Context`_.

Ensure Consistent Caching Behaviour
-----------------------------------
Ensure Consistent Caching Behavior
----------------------------------

Varnish uses the cache headers sent by your application to determine how
to cache content. However, versions prior to Varnish 4 did not respect
Expand Down Expand Up @@ -143,7 +134,7 @@ using Varnish 3:
Enable Edge Side Includes (ESI)
-------------------------------

As explained in the :ref:`Edge Side Includes section<edge-side-includes>`,
As explained in the :ref:`Edge Side Includes section <edge-side-includes>`,
Symfony detects whether it talks to a reverse proxy that understands ESI or
not. When you use the Symfony reverse proxy, you don't need to do anything.
But to make Varnish instead of Symfony resolve the ESI tags, you need some
Expand All @@ -168,10 +159,11 @@ application:
.. note::

The ``abc`` part of the header isn't important unless you have multiple "surrogates"
that need to advertise their capabilities. See `Surrogate-Capability Header`_ for details.
The ``abc`` part of the header isn't important unless you have multiple
"surrogates" that need to advertise their capabilities. See
`Surrogate-Capability Header`_ for details.

Then, optimize Varnish so that it only parses the Response contents when there
Then, optimize Varnish so that it only parses the response contents when there
is at least one ESI tag by checking the ``Surrogate-Control`` header that
Symfony adds automatically:

Expand Down
27 changes: 19 additions & 8 deletions cookbook/configuration/apache_router.rst
Expand Up @@ -4,8 +4,18 @@
How to Use the Apache Router
============================

Symfony, while fast out of the box, also provides various ways to increase that speed with a little bit of tweaking.
One of these ways is by letting Apache handle routes directly, rather than using Symfony for this task.
.. caution::

**Using the Apache Router is no longer considered a good practice**.
The small increase obtained in the application routing performance is not
worth the hassle of continuously updating the routes configuration.

The Apache Router will be removed in Symfony 3 and it's highly recommended
to not use it in your applications.

Symfony, while fast out of the box, also provides various ways to increase that
speed with a little bit of tweaking. One of these ways is by letting Apache
handle routes directly, rather than using Symfony for this task.

.. caution::

Expand Down Expand Up @@ -68,20 +78,20 @@ To test that it's working, create a very basic route for the AppBundle:
# app/config/routing.yml
hello:
path: /hello/{name}
defaults: { _controller: AppBundle:Demo:hello }
defaults: { _controller: AppBundle:Greet:hello }
.. code-block:: xml
<!-- app/config/routing.xml -->
<route id="hello" path="/hello/{name}">
<default key="_controller">AppBundle:Demo:hello</default>
<default key="_controller">AppBundle:Greet:hello</default>
</route>
.. code-block:: php
// app/config/routing.php
$collection->add('hello', new Route('/hello/{name}', array(
'_controller' => 'AppBundle:Demo:hello',
'_controller' => 'AppBundle:Greet:hello',
)));
Now generate the mod_rewrite rules:
Expand All @@ -100,7 +110,7 @@ Which should roughly output the following:
# hello
RewriteCond %{REQUEST_URI} ^/hello/([^/]+?)$
RewriteRule .* app.php [QSA,L,E=_ROUTING__route:hello,E=_ROUTING_name:%1,E=_ROUTING__controller:AppBundle\:Demo\:hello]
RewriteRule .* app.php [QSA,L,E=_ROUTING__route:hello,E=_ROUTING_name:%1,E=_ROUTING__controller:AppBundle\:Greet\:hello]
You can now rewrite ``web/.htaccess`` to use the new rules, so with this example
it should look like this:
Expand All @@ -116,12 +126,13 @@ it should look like this:
# hello
RewriteCond %{REQUEST_URI} ^/hello/([^/]+?)$
RewriteRule .* app.php [QSA,L,E=_ROUTING__route:hello,E=_ROUTING_name:%1,E=_ROUTING__controller:AppBundle\:Demo\:hello]
RewriteRule .* app.php [QSA,L,E=_ROUTING__route:hello,E=_ROUTING_name:%1,E=_ROUTING__controller:AppBundle\:Greet\:hello]
</IfModule>
.. note::

The procedure above should be done each time you add/change a route if you want to take full advantage of this setup.
The procedure above should be done each time you add/change a route if you
want to take full advantage of this setup.

That's it!
You're now all set to use Apache routes.
Expand Down
38 changes: 20 additions & 18 deletions cookbook/configuration/environments.rst
Expand Up @@ -20,7 +20,7 @@ Different Environments, different Configuration Files
-----------------------------------------------------

A typical Symfony application begins with three environments: ``dev``,
``prod``, and ``test``. As discussed, each "environment" simply represents
``prod``, and ``test``. As mentioned, each environment simply represents
a way to execute the same codebase with different configuration. It should
be no surprise then that each environment loads its own individual configuration
file. If you're using the YAML configuration format, the following files
Expand Down Expand Up @@ -55,8 +55,8 @@ multiple environments in an elegant, powerful and transparent way.

Of course, in reality, each environment differs only somewhat from others.
Generally, all environments will share a large base of common configuration.
Opening the "dev" configuration file, you can see how this is accomplished
easily and transparently:
Opening the ``config_dev.yml`` configuration file, you can see how this is
accomplished easily and transparently:

.. configuration-block::

Expand Down Expand Up @@ -86,7 +86,8 @@ simply first imports from a central configuration file (``config.yml``).
The remainder of the file can then deviate from the default configuration
by overriding individual parameters. For example, by default, the ``web_profiler``
toolbar is disabled. However, in the ``dev`` environment, the toolbar is
activated by modifying the default value in the ``dev`` configuration file:
activated by modifying the value of the ``toolbar`` option in the ``config_dev.yml``
configuration file:

.. configuration-block::

Expand Down Expand Up @@ -151,9 +152,9 @@ used by each is explicitly set::

// ...

As you can see, the ``prod`` key specifies that this application will run
in the ``prod`` environment. A Symfony application can be executed in any
environment by using this code and changing the environment string.
The ``prod`` key specifies that this application will run in the ``prod``
environment. A Symfony application can be executed in any environment by using
this code and changing the environment string.

.. note::

Expand Down Expand Up @@ -325,9 +326,7 @@ The new environment is now accessible via::
certain environments, for debugging purposes, may give too much information
about the application or underlying infrastructure. To be sure these environments
aren't accessible, the front controller is usually protected from external
IP addresses via the following code at the top of the controller:

.. code-block:: php
IP addresses via the following code at the top of the controller::

if (!in_array(@$_SERVER['REMOTE_ADDR'], array('127.0.0.1', '::1'))) {
die('You are not allowed to access this file. Check '.basename(__FILE__).' for more information.');
Expand Down Expand Up @@ -361,17 +360,20 @@ the directory of the environment you're using (most commonly ``dev`` while
developing and debugging). While it can vary, the ``app/cache/dev`` directory
includes the following:

* ``appDevDebugProjectContainer.php`` - the cached "service container" that
represents the cached application configuration;
``appDevDebugProjectContainer.php``
The cached "service container" that represents the cached application
configuration.

* ``appDevUrlGenerator.php`` - the PHP class generated from the routing
configuration and used when generating URLs;
``appDevUrlGenerator.php``
The PHP class generated from the routing configuration and used when
generating URLs.

* ``appDevUrlMatcher.php`` - the PHP class used for route matching - look
here to see the compiled regular expression logic used to match incoming
URLs to different routes;
``appDevUrlMatcher.php``
The PHP class used for route matching - look here to see the compiled regular
expression logic used to match incoming URLs to different routes.

* ``twig/`` - this directory contains all the cached Twig templates.
``twig/``
This directory contains all the cached Twig templates.

.. note::

Expand Down
13 changes: 5 additions & 8 deletions cookbook/configuration/front_controllers_and_kernel.rst
Expand Up @@ -94,12 +94,10 @@ There are two methods declared in the
left unimplemented in :class:`Symfony\\Component\\HttpKernel\\Kernel`
and thus serve as `template methods`_:

* :method:`Symfony\\Component\\HttpKernel\\KernelInterface::registerBundles`,
which must return an array of all bundles needed to run the
application;

* :method:`Symfony\\Component\\HttpKernel\\KernelInterface::registerContainerConfiguration`,
which loads the application configuration.
:method:`Symfony\\Component\\HttpKernel\\KernelInterface::registerBundles`
It must return an array of all bundles needed to run the application.
:method:`Symfony\\Component\\HttpKernel\\KernelInterface::registerContainerConfiguration`
It loads the application configuration.

To fill these (small) blanks, your application needs to subclass the
Kernel and implement these methods. The resulting class is conventionally
Expand All @@ -124,8 +122,7 @@ controller to make use of the new kernel.
it might therefore make sense to add additional sub-directories,
for example ``app/admin/AdminKernel.php`` and
``app/api/ApiKernel.php``. All that matters is that your front
controller is able to create an instance of the appropriate
kernel.
controller is able to create an instance of the appropriate kernel.

Having different ``AppKernels`` might be useful to enable different front
controllers (on potentially different servers) to run parts of your application
Expand Down

0 comments on commit 2e86186

Please sign in to comment.