Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork5.3k
Updates to DI config for 3.3#7807
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Changes fromall commits
8433fc12d11347105801c049df7d9e84572c45daf42636bea9ab27f00e48bd86e6ed9470178d145500b3759e9b26de83e289e12de443aec2bc7088dee277655452c612229fd3cac3c6c12c494422adfbdFile filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -116,29 +116,15 @@ For more information on routing, see :doc:`/routing`. | ||
| .. index:: | ||
| single: Controller; Base controller class | ||
| .. _the-base-controller-class-services: | ||
| The Base Controller Classes & Services | ||
| -------------------------------------- | ||
| For convenience, Symfony comes with two optional base | ||
| :class:`Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller` and | ||
| :class:`Symfony\\Bundle\\FrameworkBundle\\Controller\\AbstractController` | ||
| classes. You can extend either to get access to a number of `helper methods`_. | ||
| Add the ``use`` statement atop the ``Controller`` class and then modify | ||
| ``LuckyController`` to extend it:: | ||
| @@ -153,11 +139,19 @@ Add the ``use`` statement atop the ``Controller`` class and then modify | ||
| // ... | ||
| } | ||
| That's it! You now have access to methods like :ref:`$this->render() <controller-rendering-templates>` | ||
| and many others that you'll learn about next. | ||
| .. tip:: | ||
| You can extend either ``Controller`` or ``AbstractController``. The difference | ||
| is that when you extend ``AbstractController``, you can't access services directly | ||
| via ``$this->get()`` or ``$this->container->get()``. This forces you to write | ||
| more robust code to access services. But if you *do* need direct access to the | ||
| container, using ``Controller`` is fine. | ||
| .. versionadded:: 3.3 | ||
| The ``AbstractController`` class was added in Symfony 3.3. | ||
| .. index:: | ||
| single: Controller; Redirecting | ||
| @@ -244,15 +238,121 @@ The Symfony templating system and Twig are explained more in the | ||
| .. _controller-accessing-services: | ||
| Fetching Services as Controller Arguments | ||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| .. versionadded:: 3.3 | ||
| The ability to type-hint a controller argument in order to receive a service | ||
| was added in Symfony 3.3. | ||
| Symfony comes *packed* with a lot of useful objects, called :doc:`services </service_container>`. | ||
| These are used for rendering templates, sending emails, querying the database and | ||
| any other "work" you can think of. | ||
| If you need a service in a controller, just type-hint an argument with its class | ||
| (or interface) name. Symfony will automatically pass you the service you need:: | ||
| use Psr\Log\LoggerInterface | ||
| // ... | ||
| /** | ||
| * @Route("/lucky/number/{max}") | ||
| */ | ||
| public function numberAction($max, LoggerInterface $logger) | ||
| { | ||
| $logger->info('We are logging!'); | ||
| // ... | ||
| } | ||
| Awesome! | ||
| What other services can you type-hint? To see them, use the ``debug:container`` console | ||
| command: | ||
| .. code-block:: terminal | ||
| $ php bin/console debug:container --types | ||
| If you need control over the *exact* value of an argument, you can override your | ||
| controller's service config: | ||
| .. configuration-block:: | ||
| .. code-block:: yaml | ||
| # app/config/services.yml | ||
| services: | ||
| # ... | ||
| # explicitly configure the service | ||
| AppBundle\Controller\LuckyController: | ||
| public: true | ||
| tags: | ||
| # add multiple tags to controller multiple args | ||
| - name: controller.service_arguments | ||
| action: numberAction | ||
| argument: logger | ||
| # pass this specific service id | ||
| id: monolog.logger.doctrine | ||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Just as a reminder for me, I think it could be nice to be able to use bindings here. MemberAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. I also like bindings... we'll see how everything works out for in reality in Symfony 3.3 :). For the most part, bindings and arguments accomplish the same task (in a slightly different way). But it's interesting that bindings could also work to help with controller args - I hadn't really thought about that... seems like one use-case that makes bindings actually a bit better. | ||
| .. code-block:: xml | ||
| <!-- app/config/services.xml --> | ||
| <?xml version="1.0" encoding="UTF-8" ?> | ||
| <container xmlns="http://symfony.com/schema/dic/services" | ||
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| xsi:schemaLocation="http://symfony.com/schema/dic/services | ||
| http://symfony.com/schema/dic/services/services-1.0.xsd"> | ||
| <services> | ||
| <!-- ... --> | ||
| <!-- Explicitly configure the service --> | ||
| <service id="AppBundle\Controller\LuckyController" public="true"> | ||
| <tag | ||
| name="controller.service_arguments" | ||
| action="numberAction" | ||
| argument="logger" | ||
| id="monolog.logger.doctrine" | ||
| /> | ||
| </service> | ||
| </services> | ||
| </container> | ||
| .. code-block:: php | ||
| // app/config/services.php | ||
| use AppBundle\Controller\LuckyController; | ||
| $container->register(LuckyController::class) | ||
| ->setPublic(true) | ||
| ->addTag('controller.service_arguments', [ | ||
| 'action' => 'numberAction', | ||
| 'argument' => 'logger', | ||
| 'id' => 'monolog.logger.doctrine', | ||
| ]) | ||
| ; | ||
| You can of course also use normal :ref:`constructor injection <services-constructor-injection>` | ||
| in your controllers. | ||
| For more information about services, see the :doc:`/service_container` article. | ||
| .. note:: | ||
| If this isn't working, make sure your controller is registered as a service, | ||
| is :ref:`autoconfigured <services-autoconfigure>` and extends either | ||
| :class:`Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller` or | ||
| :class:`Symfony\\Bundle\\FrameworkBundle\\Controller\\AbstractController`. Or, | ||
| you can tag your service manually with ``controller.service_arguments``. All | ||
| of this is done for you in a fresh Symfony install. | ||
| .. _accessing-other-services: | ||
| .. _controller-access-services-directly: | ||
| Accessing the Container Directly | ||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| If you extend the base ``Controller`` class, you can access any Symfony service | ||
| via the :method:`Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller::get` | ||
| method. Here are several common services you might need:: | ||
| @@ -262,23 +362,17 @@ method. Here are several common services you might need:: | ||
| $mailer = $this->get('mailer'); | ||
| // you can also fetch parameters | ||
| $someParameter = $this->getParameter('some_parameter'); | ||
| If you receive an eror like: | ||
| .. code-block:: text | ||
| You have requested a non-existent service "my_service_id" | ||
| Check to make sure the service exists (use :ref:`debug:container <container-debug-container>`) | ||
| and that it's :ref:`public <container-public>`. | ||
| .. index:: | ||
| single: Controller; Managing errors | ||
| @@ -355,7 +449,6 @@ Symfony provides a nice session object that you can use to store information | ||
| about the user between requests. By default, Symfony stores the attributes in a | ||
| cookie by using native PHP sessions. | ||
| .. versionadded:: 3.3 | ||
| The ability to request a ``Session`` instance in controllers was introduced | ||
| in Symfony 3.3. | ||
| @@ -418,20 +511,6 @@ For example, imagine you're processing a :doc:`form </forms>` submission:: | ||
| return $this->render(...); | ||
| } | ||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Shouldn't this also be removed in the MemberAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. I think we need to re-read and re-think that article in its entirety... since controllers as services are a first-class citizen (does it make sense to still have a separate article?) | ||
| After processing the request, the controller sets a flash message in the session | ||
| and then redirects. The message key (``notice`` in this example) can be anything: | ||
| you'll use this key to retrieve the message. | ||
| @@ -636,12 +715,7 @@ and it's a PHP function where you can do anything in order to return the | ||
| final ``Response`` object that will be returned to the user. | ||
| To make life easier, you'll probably extend the base ``Controller`` class because | ||
| this gives access to shortcut methods (like ``render()`` and ``redirectToRoute()``). | ||
| In other articles, you'll learn how to use specific services from inside your controller | ||
| that will help you persist and fetch objects from a database, process form submissions, | ||
| @@ -666,4 +740,5 @@ Learn more about Controllers | ||
| controller/* | ||
| .. _`helper methods`: https://github.com/symfony/symfony/blob/master/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerTrait.php | ||
Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. What about document the trait in the reference section instead? MemberAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. I'm not sure why, but the API docs for the trait areterrible, basically empty :/. It's actually a problem because Iwould like to link to some methods in the trait via | ||
| .. _`unvalidated redirects security vulnerability`: https://www.owasp.org/index.php/Open_redirect | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -548,6 +548,7 @@ a controller, this is pretty easy. Add the following method to the | ||
| // ... | ||
| use AppBundle\Entity\Product; | ||
| use Symfony\Component\HttpFoundation\Response; | ||
| use Doctrine\ORM\EntityManagerInterface; | ||
| // ... | ||
| public function createAction() | ||
| @@ -568,6 +569,12 @@ a controller, this is pretty easy. Add the following method to the | ||
| return new Response('Saved new product with id '.$product->getId()); | ||
| } | ||
| // you can also receive the $em as an argument | ||
| public function editAction(EntityManagerInterface $em) | ||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Can we also add this to the MemberAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. I'll update the whole Doctrine section in another PR with more of this fancy type-based stuff :) | ||
| { | ||
| // ... | ||
| } | ||
| .. note:: | ||
| If you're following along with this example, you'll need to create a | ||
Uh oh!
There was an error while loading.Please reload this page.