Skip to content

Commit

Permalink
updated code for Symfony 2.3 and made minor tweaks to the text
Browse files Browse the repository at this point in the history
  • Loading branch information
fabpot committed May 15, 2013
1 parent f3c151c commit d802d42
Show file tree
Hide file tree
Showing 10 changed files with 57 additions and 62 deletions.
25 changes: 13 additions & 12 deletions book/part01.rst
Original file line number Diff line number Diff line change
Expand Up @@ -53,20 +53,21 @@ Symfony2 Components.
based on the Symfony2 Components. The code is rather slim and it leverages
many aspects of the Symfony2 Components.

Many modern web frameworks call themselves MVC frameworks. We won't talk about
MVC here as the Symfony2 Components are able to create any type of frameworks,
not just the ones that follow the MVC architecture. Anyway, if you have a look
at the MVC semantics, this book is about how to create the Controller part of
a framework. For the Model and the View, it really depends on your personal
taste and I will let you use any existing third-party libraries (Doctrine,
Propel, or plain-old PDO for the Model; PHP or Twig for the View).
Many modern web frameworks advertize themselves as being MVC frameworks. We
won't talk about the MVC pattern as the Symfony2 Components are able to create
any type of frameworks, not just the ones that follow the MVC architecture.
Anyway, if you have a look at the MVC semantics, this book is about how to
create the Controller part of a framework. For the Model and the View, it
really depends on your personal taste and I will let you use any existing
third-party libraries (Doctrine, Propel, or plain-old PDO for the Model; PHP
or Twig for the View).

When creating a framework, following the MVC pattern is not the right goal.
The main goal should be the Separation of Concerns; I actually think that this
is the only design pattern that you should really care about. The fundamental
principles of the Symfony2 Components are focused on the HTTP specification.
As such, the frameworks that we are going to create should be more accurately
labelled as HTTP frameworks or Request/Response frameworks.
The main goal should be the **Separation of Concerns**; I actually think that
this is the only design pattern that you should really care about. The
fundamental principles of the Symfony2 Components are focused on the HTTP
specification. As such, the frameworks that we are going to create should be
more accurately labelled as HTTP frameworks or Request/Response frameworks.

Before we start
---------------
Expand Down
17 changes: 9 additions & 8 deletions book/part02.rst
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ dependency for the project:
{
"require": {
"symfony/http-foundation": "2.1.*"
"symfony/http-foundation": "~2.3"
}
}
Expand Down Expand Up @@ -170,8 +170,8 @@ first outputs the HTTP headers followed by the content).
Before the ``send()`` call, we should have added a call to the
``prepare()`` method (``$response->prepare($request);``) to ensure that
our Response were compliant with the HTTP specification. For instance, if
we were to call the page with the ``HEAD`` method, it would have removed
the content of the Response.
we were to call the page with the ``HEAD`` method, it would remove the
content of the Response.

The main difference with the previous code is that you have total control of
the HTTP messages. You can create whatever request you want and you are in
Expand Down Expand Up @@ -275,11 +275,12 @@ secure? The ``$_SERVER['HTTP_X_FORWARDED_FOR']`` value cannot be trusted as it
can be manipulated by the end user when there is no proxy. So, if you are
using this code in production without a proxy, it becomes trivially easy to
abuse your system. That's not the case with the ``getClientIp()`` method as
you must explicitly trust this header by calling ``trustProxyData()``::
you must explicitly trust your reverse proxies by calling
``setTrustedProxies()``::

<?php

Request::trustProxyData();
Request::setTrustedProxies(array('10.0.0.1'));

if ($myIp == $request->getClientIp(true)) {
// the client is a known one, so give it some more privilege
Expand All @@ -302,9 +303,9 @@ Using just the Symfony2 HttpFoundation component already allows you to write
better and more testable code. It also allows you to write code faster as many
day-to-day problems have already been solved for you.

As a matter of fact, projects like Drupal have adopted (for the upcoming
version 8) the HttpFoundation component; if it works for them, it will
probably work for you. Don't reinvent the wheel.
As a matter of fact, projects like Drupal have adopted the HttpFoundation
component; if it works for them, it will probably work for you. Don't reinvent
the wheel.

I've almost forgot to talk about one added benefit: using the HttpFoundation
component is the start of better interoperability between all frameworks and
Expand Down
12 changes: 6 additions & 6 deletions book/part03.rst
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ And for the "Goodbye" page::

We have indeed moved most of the shared code into a central place, but it does
not feel like a good abstraction, doesn't it? First, we still have the
``send()`` method in all pages, then our pages does not look like templates,
and we are still not able to test this code properly.
``send()`` method in all pages, then our pages do not look like templates, and
we are still not able to test this code properly.

Moreover, adding a new page means that we need to create a new PHP script,
which name is exposed to the end user via the URL
Expand Down Expand Up @@ -140,9 +140,9 @@ To access a page, you must now use the ``front.php`` script:
able to type ``http://example.com/hello?name=Fabien``, which looks much
better.

So, the trick is the usage of the ``Request::getPathInfo()`` method which
returns the path of the Request by removing the front controller script name
including its sub-directories (only if needed -- see above tip).
The trick is the usage of the ``Request::getPathInfo()`` method which returns
the path of the Request by removing the front controller script name including
its sub-directories (only if needed -- see above tip).

.. tip::

Expand Down Expand Up @@ -205,7 +205,7 @@ And the ``hello.php`` script can now be converted to a template::

Hello <?php echo htmlspecialchars($name, ENT_QUOTES, 'UTF-8') ?>

We have our framework for today::
We have the first version of our framework::

<?php

Expand Down
13 changes: 3 additions & 10 deletions book/part04.rst
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ update`` command to install it:
{
"require": {
"symfony/http-foundation": "2.1.*",
"symfony/routing": "2.1.*"
"symfony/http-foundation": "~2.3",
"symfony/routing": "~2.3"
}
}
Expand Down Expand Up @@ -181,7 +181,7 @@ There are a few new things in the code::

Hello <?php echo htmlspecialchars($name, ENT_QUOTES, 'UTF-8') ?>

* Routes configuration has been moved to its own file:
* Route configuration has been moved to its own file:

.. code-block:: php
Expand Down Expand Up @@ -232,11 +232,4 @@ generate absolute URLs::

echo $dumper->dump();

Want even more performance? Dump your routes as a set of Apache rewrite
rules::

$dumper = new Routing\Matcher\Dumper\ApacheMatcherDumper($routes);

echo $dumper->dump();

.. _`documentation`: http://symfony.com/doc/current/components/routing.html
12 changes: 6 additions & 6 deletions book/part05.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ As the rendering is now done by an external function (``render_template()``
here), we need to pass to it the attributes extracted from the URL. We could
have passed them as an additional argument to ``render_template()``, but
instead, let's use another feature of the ``Request`` class called
*attributes*: Request attributes lets you attach additional information about
the Request that is not directly related to the HTTP Request data.
*attributes*: Request attributes is a way to attach additional information
about the Request that is not directly related to the HTTP Request data.

You can now create the ``render_template()`` function, a generic controller
that renders a template when there is no specific logic. To keep the same
Expand Down Expand Up @@ -177,10 +177,10 @@ framework does not need to be modified in any way, just create a new
return $routes;

The ``is_leap_year()`` function returns ``true`` when the given year is a leap
year, ``false`` otherwise. If the year is null, the current year is tested.
The controller is simple: it gets the year from the request attributes, pass
it to the `is_leap_year()`` function, and according to the return value it
creates a new Response object.
year, ``false`` otherwise. If the year is ``null``, the current year is
tested. The controller is simple: it gets the year from the request
attributes, pass it to the `is_leap_year()`` function, and according to the
return value it creates a new Response object.

As always, you can decide to stop here and use the framework as is; it's
probably all you need to create simple websites like those fancy one-page
Expand Down
8 changes: 4 additions & 4 deletions book/part06.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ component::

{
"require": {
"symfony/http-foundation": "2.1.*",
"symfony/routing": "2.1.*",
"symfony/http-kernel": "2.1.*"
"symfony/http-foundation": "~2.3",
"symfony/routing": "~2.3",
"symfony/http-kernel": "~2.3"
}
}

Expand Down Expand Up @@ -145,7 +145,7 @@ method is not defined, an argument has no matching attribute, ...).

With the great flexibility of the default controller resolver, you might
wonder why someone would want to create another one (why would there be an
interface if not). Two examples: in Symfony2, ``getController()`` is
interface if not?). Two examples: in Symfony2, ``getController()`` is
enhanced to support `controllers as services`_; and in
`FrameworkExtraBundle`_, ``getArguments()`` is enhanced to support
parameter converters, where request attributes are converted to objects
Expand Down
8 changes: 4 additions & 4 deletions book/part07.rst
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,12 @@ be autoloaded, update the ``composer.json`` file:
{
"require": {
"symfony/http-foundation": "2.1.*",
"symfony/routing": "2.1.*",
"symfony/http-kernel": "2.1.*"
"symfony/http-foundation": "~2.3",
"symfony/routing": "~2.3",
"symfony/http-kernel": "~2.3"
},
"autoload": {
"psr-0": { "Simplex": "src/", "Calendar": "src/" }
"psr-0": { "Simplex\\": "src/", "Calendar\\": "src/" }
}
}
Expand Down
10 changes: 5 additions & 5 deletions book/part09.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ version of this pattern:
{
"require": {
"symfony/http-foundation": "2.1.*",
"symfony/routing": "2.1.*",
"symfony/http-kernel": "2.1.*",
"symfony/event-dispatcher": "2.1.*"
"symfony/http-foundation": "~2.3",
"symfony/routing": "~2.3",
"symfony/http-kernel": "~2.3",
"symfony/event-dispatcher": "~2.3"
},
"autoload": {
"psr-0": { "Simplex": "src/", "Calendar": "src/" }
"psr-0": { "Simplex\\": "src/", "Calendar\\": "src/" }
}
}
Expand Down
2 changes: 1 addition & 1 deletion book/part11.rst
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ The error controller reads as follows::
Voilà! Clean and customizable error management without efforts. And of course,
if your controller throws an exception, HttpKernel will handle it nicely.

In part 2, we have talked about the ``Response::prepare()`` method, which
In chapter two, we talked about the ``Response::prepare()`` method, which
ensures that a Response is compliant with the HTTP specification. It is
probably a good idea to always call it just before sending the Response to the
client; that's what the ``ResponseListener`` does::
Expand Down
12 changes: 6 additions & 6 deletions book/part12.rst
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,14 @@ container:
{
"require": {
"symfony/http-foundation": "2.1.*",
"symfony/routing": "2.1.*",
"symfony/http-kernel": "2.1.*",
"symfony/event-dispatcher": "2.1.*",
"symfony/dependency-injection": "2.1.*"
"symfony/http-foundation": "~2.3",
"symfony/routing": "~2.3",
"symfony/http-kernel": "~2.3",
"symfony/event-dispatcher": "~2.3",
"symfony/dependency-injection": "~2.3"
},
"autoload": {
"psr-0": { "Simplex": "src/", "Calendar": "src/" }
"psr-0": { "Simplex\\": "src/", "Calendar\\": "src/" }
}
}
Expand Down

0 comments on commit d802d42

Please sign in to comment.