Commit 5b1a28cf authored by Fabien Potencier's avatar Fabien Potencier

Merge remote branch 'igorw/more-docs'

* igorw/more-docs:
  [docs] a section about common pitfalls
  [docs] style adjustment
  [docs] emphasis on "let's go"
  [docs] explain the purpose of the JsonUserPersister
  [docs] add cross-references to Symfony2 API docs
  [docs] several small adjustments
parents bad9cf84 a34f2995
...@@ -14,6 +14,10 @@ steps. ...@@ -14,6 +14,10 @@ steps.
* Send a pull request. Bonus points for topic branches. * Send a pull request. Bonus points for topic branches.
If you have a big change or would like to discuss something,
please join us on the `mailing list
<http://groups.google.com/group/silex-php>`.
.. note:: .. note::
Any code you contribute must be licensed under the MIT Any code you contribute must be licensed under the MIT
......
...@@ -105,7 +105,7 @@ or the PEAR Naming Convention, it is possible to autoload ...@@ -105,7 +105,7 @@ or the PEAR Naming Convention, it is possible to autoload
classes using the ``UniversalClassLoader``. classes using the ``UniversalClassLoader``.
As described in the *Services* chapter, there is an As described in the *Services* chapter, there is an
*autoloader* service that you can use for this. *autoloader* service which can be used for this.
Here is an example of how to use it (based on `Buzz <https://github.com/kriswallsmith/Buzz>`_):: Here is an example of how to use it (based on `Buzz <https://github.com/kriswallsmith/Buzz>`_)::
......
...@@ -24,14 +24,14 @@ Parameters ...@@ -24,14 +24,14 @@ Parameters
Services Services
-------- --------
* **twig**: The ``Twig_Environment`` instance, you will only * **twig**: The ``Twig_Environment`` instance. The main way of
need to use this. interacting with Twig.
* **twig.configure**: Protected closure that takes the twig * **twig.configure**: Protected closure that takes the Twig
environment as an argument. You can use it to add more environment as an argument. You can use it to add more
custom globals. custom globals.
* **twig.loader**: The loader for twig templates which uses * **twig.loader**: The loader for Twig templates which uses
the ``twig.path`` and the ``twig.templates`` options. You the ``twig.path`` and the ``twig.templates`` options. You
can also replace the loader completely. can also replace the loader completely.
......
...@@ -12,9 +12,11 @@ None. ...@@ -12,9 +12,11 @@ None.
Services Services
-------- --------
* **url_generator**: An instance of * **url_generator**: An instance of `UrlGenerator
``Symfony\Component\Routing\Generator\UrlGenerator``, using the <http://api.symfony.com/2.0/Symfony/Component/Routing/Generator/UrlGenerator.html>`_,
``RouteCollection`` that is provided through the ``routes`` service. using the `RouteCollection
<http://api.symfony.com/2.0/Symfony/Component/Routing/RouteCollection.html>`_
that is provided through the ``routes`` service.
It has a ``generate`` method, which takes the route name as an argument, It has a ``generate`` method, which takes the route name as an argument,
followed by an array of route parameters. followed by an array of route parameters.
......
...@@ -11,16 +11,20 @@ Application ...@@ -11,16 +11,20 @@ Application
~~~~~~~~~~~ ~~~~~~~~~~~
The application is the main interface to Silex. It The application is the main interface to Silex. It
implements Symfony2's ``HttpKernelInterface``, so you can implements Symfony2's `HttpKernelInterface
pass a ``Request`` to the ``handle`` method and it will <http://api.symfony.com/2.0/Symfony/Component/HttpKernel/HttpKernelInterface.html>`_,
return a ``Response``. so you can pass a `Request
<http://api.symfony.com/2.0/Symfony/Component/HttpFoundation/Request.html>`_
to the ``handle`` method and it will return a `Response
<http://api.symfony.com/2.0/Symfony/Component/HttpFoundation/Response.html>`_.
It extends the ``Pimple`` service container, allowing It extends the ``Pimple`` service container, allowing
for flexibility on the outside as well as the inside. you for flexibility on the outside as well as the inside. you
could replace any service, and you are also able to read could replace any service, and you are also able to read
them. them.
The application makes strong use of the ``EventDispatcher`` The application makes strong use of the `EventDispatcher
<http://api.symfony.com/2.0/Symfony/Component/EventDispatcher/EventDispatcher.html>`_
to hook into the Symfony2 HttpKernel events. This allows to hook into the Symfony2 HttpKernel events. This allows
fetching the ``Request``, converting string responses into fetching the ``Request``, converting string responses into
``Response`` objects and handling Exceptions. We also use it ``Response`` objects and handling Exceptions. We also use it
...@@ -30,7 +34,9 @@ errors. ...@@ -30,7 +34,9 @@ errors.
Controller Controller
~~~~~~~~~~ ~~~~~~~~~~
The Symfony2 ``Route`` is actually quite powerful. Routes The Symfony2 `Route
<http://api.symfony.com/2.0/Symfony/Component/Routing/Route.html>`_
is actually quite powerful. Routes
can be named, which allows for URL generation. They can can be named, which allows for URL generation. They can
also have requirements for the variable parts. In order also have requirements for the variable parts. In order
to allow settings these through a nice interface the to allow settings these through a nice interface the
...@@ -41,8 +47,9 @@ a route. ...@@ -41,8 +47,9 @@ a route.
ControllerCollection ControllerCollection
~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~
One of the goals of exposing the ``RouteCollection`` was One of the goals of exposing the `RouteCollection
to make it mutable, so extensions could add stuff to it. <http://api.symfony.com/2.0/Symfony/Component/Routing/RouteCollection.html>`_
was to make it mutable, so extensions could add stuff to it.
The challenge here is the fact that routes know nothing The challenge here is the fact that routes know nothing
about their name. The name only has meaning in context about their name. The name only has meaning in context
of the ``RouteCollection`` and cannot be changed. of the ``RouteCollection`` and cannot be changed.
...@@ -51,7 +58,7 @@ To solve this challenge we came up with a staging area ...@@ -51,7 +58,7 @@ To solve this challenge we came up with a staging area
for routes. The ``ControllerCollection`` holds the for routes. The ``ControllerCollection`` holds the
controllers until ``flush`` is called, at which point controllers until ``flush`` is called, at which point
the routes are added to the ``RouteCollection``. Also, the routes are added to the ``RouteCollection``. Also,
the controllers are frozen. This means that they can the controllers are then frozen. This means that they can
no longer be modified and will throw an Exception if no longer be modified and will throw an Exception if
you try to do so. you try to do so.
...@@ -60,7 +67,7 @@ could be found, which is why flushing is now always ...@@ -60,7 +67,7 @@ could be found, which is why flushing is now always
explicit. The Application will flush, but if you want explicit. The Application will flush, but if you want
to read the ``ControllerCollection`` before the to read the ``ControllerCollection`` before the
request takes place, you will have to call flush request takes place, you will have to call flush
first. yourself.
The ``Application`` provides a shortcut ``flush`` The ``Application`` provides a shortcut ``flush``
method for flushing the ``ControllerCollection``. method for flushing the ``ControllerCollection``.
...@@ -79,3 +86,6 @@ Following Symfony2 components are used by Silex: ...@@ -79,3 +86,6 @@ Following Symfony2 components are used by Silex:
* **Routing**: For matching defined routes. * **Routing**: For matching defined routes.
* **EventDispatcher**: For hooking into the HttpKernel. * **EventDispatcher**: For hooking into the HttpKernel.
For more information, `check out the Symfony website
<http://symfony.com/>`_.
...@@ -20,7 +20,7 @@ Silex aims to be: ...@@ -20,7 +20,7 @@ Silex aims to be:
In a nutshell, you define controllers and map them to routes, all in one In a nutshell, you define controllers and map them to routes, all in one
step. step.
Let's go! :: **Let's go!** ::
require_once __DIR__.'/silex.phar'; require_once __DIR__.'/silex.phar';
......
...@@ -17,7 +17,8 @@ to services instead of creating them from within the service or ...@@ -17,7 +17,8 @@ to services instead of creating them from within the service or
relying on globals. This generally leads to code that is decoupled, relying on globals. This generally leads to code that is decoupled,
re-usable, flexible and testable. re-usable, flexible and testable.
Here is an example:: Here is an example of a class that takes a ``User`` object and stores
it as a file in JSON format::
class JsonUserPersister class JsonUserPersister
{ {
...@@ -97,8 +98,8 @@ Service definitions ...@@ -97,8 +98,8 @@ Service definitions
Defining services is no different than defining parameters. Defining services is no different than defining parameters.
You just set an array key on the container to be a closure. You just set an array key on the container to be a closure.
The difference is, when you retrieve the service, the However, when you retrieve the service, the closure is executed.
closure is executed. This allows for lazy service creation. This allows for lazy service creation.
:: ::
...@@ -180,15 +181,16 @@ from being executed, by using the ``protect`` method. ...@@ -180,15 +181,16 @@ from being executed, by using the ``protect`` method.
Note that protected closures do not get access to Note that protected closures do not get access to
the container. the container.
Predefined services Core services
------------------- -------------
Silex defines a range of services which can be used Silex defines a range of services which can be used
or replaced. You probably don't want to mess with most or replaced. You probably don't want to mess with most
of them. of them.
* **request**: Contains the current request object, * **request**: Contains the current request object,
which is an instance of ``Symfony\Component\HttpFoundation\Request``. which is an instance of `Request
<http://api.symfony.com/2.0/Symfony/Component/HttpFoundation/Request.html>`_.
It gives you access to ``GET``, ``POST`` parameters It gives you access to ``GET``, ``POST`` parameters
and lots more! and lots more!
...@@ -197,7 +199,8 @@ of them. ...@@ -197,7 +199,8 @@ of them.
$id = $app['request']->get('id'); $id = $app['request']->get('id');
* **autoloader**: This service provides you with a * **autoloader**: This service provides you with a
``Symfony\Component\ClassLoader\UniversalClassLoader`` `UniversalClassLoader
<http://api.symfony.com/2.0/Symfony/Component/ClassLoader/UniversalClassLoader.html>`_
that is already registered. You can register prefixes that is already registered. You can register prefixes
and namespaces on it. and namespaces on it.
...@@ -205,7 +208,8 @@ of them. ...@@ -205,7 +208,8 @@ of them.
$app['autoloader']->registerPrefix('Twig_', $app['twig.class_path']); $app['autoloader']->registerPrefix('Twig_', $app['twig.class_path']);
* **routes**: The ``Symfony\Component\Routing\RouteCollection`` * **routes**: The `RouteCollection
<http://api.symfony.com/2.0/Symfony/Component/Routing/RouteCollection.html>`_
that is used internally. You can add, modify, read that is used internally. You can add, modify, read
routes. routes.
...@@ -213,15 +217,18 @@ of them. ...@@ -213,15 +217,18 @@ of them.
that is used internally. Check the *Internals* that is used internally. Check the *Internals*
chapter for more information. chapter for more information.
* **dispatcher**: The ``Symfony\Component\EventDispatcher\EventDispatcher`` * **dispatcher**: The `EventDispatcher
<http://api.symfony.com/2.0/Symfony/Component/EventDispatcher/EventDispatcher.html>`_
that is used internally. It is the core of the Symfony2 that is used internally. It is the core of the Symfony2
system and is used quite a bit by Silex. system and is used quite a bit by Silex.
* **resolver**: The ``Symfony\Component\HttpKernel\Controller\ControllerResolver`` * **resolver**: The `ControllerResolver
<http://api.symfony.com/2.0/Symfony/Component/HttpKernel/Controller/ControllerResolver.html>`_
that is used internally. It takes care of executing the that is used internally. It takes care of executing the
controller with the right arguments. controller with the right arguments.
* **kernel**: The ``Symfony\Component\HttpKernel\HttpKernel`` * **kernel**: The `HttpKernel
<http://api.symfony.com/2.0/Symfony/Component/HttpKernel/HttpKernel.html>`_
that is used internally. The HttpKernel is the heart of that is used internally. The HttpKernel is the heart of
Symfony2, it takes a Request as input and returns a Symfony2, it takes a Request as input and returns a
Response as output. Response as output.
......
...@@ -27,7 +27,7 @@ The use statement aliases ``Silex\Application`` to ``Application``. ...@@ -27,7 +27,7 @@ The use statement aliases ``Silex\Application`` to ``Application``.
One other thing you have to do is configure your web server. If you One other thing you have to do is configure your web server. If you
are using apache you can use a ``.htaccess`` file for this. are using apache you can use a ``.htaccess`` file for this.
.. code-block:: text .. code-block:: apache
<IfModule mod_rewrite.c> <IfModule mod_rewrite.c>
RewriteEngine On RewriteEngine On
...@@ -176,16 +176,19 @@ set up a message and send that message. ...@@ -176,16 +176,19 @@ set up a message and send that message.
The current ``request`` service is retrieved using the array key syntax. The current ``request`` service is retrieved using the array key syntax.
You can find more information about services in the *Services* chapter. You can find more information about services in the *Services* chapter.
The request is an instance of ``Symfony\Component\HttpFoundation\Request``, The request is an instance of `Request
<http://api.symfony.com/2.0/Symfony/Component/HttpFoundation/Request.html>`_,
so you can fetch variables using the request's ``get`` method. so you can fetch variables using the request's ``get`` method.
Instead of returning a string we are returning an instance of Instead of returning a string we are returning an instance of
``Symfony\Component\HttpFoundation\Response``. This allows setting an HTTP `Response
<http://api.symfony.com/2.0/Symfony/Component/HttpFoundation/Response.html>`_.
This allows setting an HTTP
status code, in this case it is set to ``201 Created``. status code, in this case it is set to ``201 Created``.
.. note:: .. note::
Silex always uses ``Response`` internally, it converts strings to Silex always uses a ``Response`` internally, it converts strings to
responses with status code ``200 Ok``. responses with status code ``200 Ok``.
Other methods Other methods
...@@ -209,7 +212,7 @@ can also call ``match``, which will match all methods. ...@@ -209,7 +212,7 @@ can also call ``match``, which will match all methods.
Route variables Route variables
~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~
As has been before you can define variable parts in a route like this:: As has been show before you can define variable parts in a route like this::
$app->get('/blog/show/{id}', function($id) { $app->get('/blog/show/{id}', function($id) {
... ...
...@@ -251,7 +254,7 @@ You can also chain these calls:: ...@@ -251,7 +254,7 @@ You can also chain these calls::
->assert('commentId', '\d+'); ->assert('commentId', '\d+');
Named routes Named routes
~~~~~~~~~~~~~~~ ~~~~~~~~~~~~
Certain extensions (such as ``UrlGenerator``) can make use of named routes. Certain extensions (such as ``UrlGenerator``) can make use of named routes.
By default Silex will generate a route name for you, that cannot really be By default Silex will generate a route name for you, that cannot really be
...@@ -343,3 +346,26 @@ you can create by calling the ``redirect`` method:: ...@@ -343,3 +346,26 @@ you can create by calling the ``redirect`` method::
}); });
This will redirect from ``/`` to ``/hello``. This will redirect from ``/`` to ``/hello``.
Pitfalls
--------
There are some things that can go wrong. Here we will try and outline the
most frequent ones.
PHP configuration
~~~~~~~~~~~~~~~~~
Certain PHP distributions have restrictive default Phar settings. Setting
the following may help.
.. code-block:: ini
phar.readonly = Off
phar.require_hash = Off
If you are on Suhosin you will also have to set this:
.. code-block:: ini
suhosin.executor.include.whitelist = phar
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment