You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{"payload":{"allShortcutsEnabled":false,"fileTree":{"":{"items":[{"name":".github","path":".github","contentType":"directory"},{"name":".platform","path":".platform","contentType":"directory"},{"name":"_build","path":"_build","contentType":"directory"},{"name":"_images","path":"_images","contentType":"directory"},{"name":"_includes","path":"_includes","contentType":"directory"},{"name":"assetic","path":"assetic","contentType":"directory"},{"name":"best_practices","path":"best_practices","contentType":"directory"},{"name":"bundles","path":"bundles","contentType":"directory"},{"name":"components","path":"components","contentType":"directory"},{"name":"configuration","path":"configuration","contentType":"directory"},{"name":"console","path":"console","contentType":"directory"},{"name":"contributing","path":"contributing","contentType":"directory"},{"name":"controller","path":"controller","contentType":"directory"},{"name":"create_framework","path":"create_framework","contentType":"directory"},{"name":"debug","path":"debug","contentType":"directory"},{"name":"deployment","path":"deployment","contentType":"directory"},{"name":"doctrine","path":"doctrine","contentType":"directory"},{"name":"email","path":"email","contentType":"directory"},{"name":"event_dispatcher","path":"event_dispatcher","contentType":"directory"},{"name":"form","path":"form","contentType":"directory"},{"name":"frontend","path":"frontend","contentType":"directory"},{"name":"getting_started","path":"getting_started","contentType":"directory"},{"name":"http_cache","path":"http_cache","contentType":"directory"},{"name":"introduction","path":"introduction","contentType":"directory"},{"name":"logging","path":"logging","contentType":"directory"},{"name":"profiler","path":"profiler","contentType":"directory"},{"name":"quick_tour","path":"quick_tour","contentType":"directory"},{"name":"reference","path":"reference","contentType":"directory"},{"name":"request","path":"request","contentType":"directory"},{"name":"routing","path":"routing","contentType":"directory"},{"name":"security","path":"security","contentType":"directory"},{"name":"serializer","path":"serializer","contentType":"directory"},{"name":"service_container","path":"service_container","contentType":"directory"},{"name":"session","path":"session","contentType":"directory"},{"name":"setup","path":"setup","contentType":"directory"},{"name":"templating","path":"templating","contentType":"directory"},{"name":"testing","path":"testing","contentType":"directory"},{"name":"translation","path":"translation","contentType":"directory"},{"name":"validation","path":"validation","contentType":"directory"},{"name":".editorconfig","path":".editorconfig","contentType":"file"},{"name":".gitignore","path":".gitignore","contentType":"file"},{"name":".platform.app.yaml","path":".platform.app.yaml","contentType":"file"},{"name":".travis.yml","path":".travis.yml","contentType":"file"},{"name":"README.markdown","path":"README.markdown","contentType":"file"},{"name":"assetic.rst","path":"assetic.rst","contentType":"file"},{"name":"bundles.rst","path":"bundles.rst","contentType":"file"},{"name":"changelog.rst","path":"changelog.rst","contentType":"file"},{"name":"configuration.rst","path":"configuration.rst","contentType":"file"},{"name":"console.rst","path":"console.rst","contentType":"file"},{"name":"controller.rst","path":"controller.rst","contentType":"file"},{"name":"debug.rst","path":"debug.rst","contentType":"file"},{"name":"deployment.rst","path":"deployment.rst","contentType":"file"},{"name":"doctrine.rst","path":"doctrine.rst","contentType":"file"},{"name":"email.rst","path":"email.rst","contentType":"file"},{"name":"event_dispatcher.rst","path":"event_dispatcher.rst","contentType":"file"},{"name":"expressions.rst","path":"expressions.rst","contentType":"file"},{"name":"forms.rst","path":"forms.rst","contentType":"file"},{"name":"frontend.rst","path":"frontend.rst","contentType":"file"},{"name":"http_cache.rst","path":"http_cache.rst","contentType":"file"},{"name":"index.rst","path":"index.rst","contentType":"file"},{"name":"logging.rst","path":"logging.rst","contentType":"file"},{"name":"page_creation.rst","path":"page_creation.rst","contentType":"file"},{"name":"performance.rst","path":"performance.rst","contentType":"file"},{"name":"profiler.rst","path":"profiler.rst","contentType":"file"},{"name":"request.rst","path":"request.rst","contentType":"file"},{"name":"routing.rst","path":"routing.rst","contentType":"file"},{"name":"security.rst","path":"security.rst","contentType":"file"},{"name":"serializer.rst","path":"serializer.rst","contentType":"file"},{"name":"service_container.rst","path":"service_container.rst","contentType":"file"},{"name":"session.rst","path":"session.rst","contentType":"file"},{"name":"setup.rst","path":"setup.rst","contentType":"file"},{"name":"templating.rst","path":"templating.rst","contentType":"file"},{"name":"testing.rst","path":"testing.rst","contentType":"file"},{"name":"translation.rst","path":"translation.rst","contentType":"file"},{"name":"validation.rst","path":"validation.rst","contentType":"file"}],"totalCount":75}},"fileTreeProcessingTime":5.677974,"foldersToFetch":[],"incompleteFileTree":false,"repo":{"id":521583,"defaultBranch":"7.3","name":"symfony-docs","ownerLogin":"symfony","currentUserCanPush":false,"isFork":false,"isEmpty":false,"createdAt":"2010-02-17T08:43:51.000Z","ownerAvatar":"https://avatars.githubusercontent.com/u/143937?v=4","public":true,"private":false,"isOrgOwned":true},"codeLineWrapEnabled":false,"symbolsExpanded":false,"treeExpanded":true,"refInfo":{"name":"3.0","listCacheKey":"v0:1751870253.0","canEdit":false,"refType":"branch","currentOid":"fdadad00a2d72106512b155f462aab1a86f2eaeb"},"path":"controller.rst","currentUser":null,"blob":{"rawLines":null,"stylingDirectives":null,"colorizedLines":null,"csv":null,"csvError":null,"dependabotInfo":{"showConfigurationBanner":false,"configFilePath":null,"networkDependabotPath":"/symfony/symfony-docs/network/updates","dismissConfigurationNoticePath":"/settings/dismiss-notice/dependabot_configuration_notice","configurationNoticeDismissed":null},"displayName":"controller.rst","displayUrl":"https://github.com/symfony/symfony-docs/blob/3.0/controller.rst?raw=true","headerInfo":{"blobSize":"17.7 KB","deleteTooltip":"You must be signed in to make or propose changes","editTooltip":"You must be signed in to make or propose changes","ghDesktopPath":"https://desktop.github.com","isGitLfs":false,"onBranch":true,"shortPath":"6adec62","siteNavLoginPath":"/login?return_to=https%3A%2F%2Fgithub.com%2Fsymfony%2Fsymfony-docs%2Fblob%2F3.0%2Fcontroller.rst","isCSV":false,"isRichtext":true,"toc":[{"level":2,"text":"Controller","anchor":"controller","htmlText":"Controller"},{"level":3,"text":"A Simple Controller","anchor":"a-simple-controller","htmlText":"A Simple Controller"},{"level":4,"text":"Mapping a URL to a Controller","anchor":"mapping-a-url-to-a-controller","htmlText":"Mapping a URL to a Controller"},{"level":3,"text":"The Base Controller Class \u0026 Services","anchor":"the-base-controller-class--services","htmlText":"The Base Controller Class \u0026amp; Services"},{"level":4,"text":"Generating URLs","anchor":"generating-urls","htmlText":"Generating URLs"},{"level":4,"text":"Redirecting","anchor":"redirecting","htmlText":"Redirecting"},{"level":4,"text":"Rendering Templates","anchor":"rendering-templates","htmlText":"Rendering Templates"},{"level":4,"text":"Accessing other Services","anchor":"accessing-other-services","htmlText":"Accessing other Services"},{"level":3,"text":"Managing Errors and 404 Pages","anchor":"managing-errors-and-404-pages","htmlText":"Managing Errors and 404 Pages"},{"level":3,"text":"The Request object as a Controller Argument","anchor":"the-request-object-as-a-controller-argument","htmlText":"The Request object as a Controller Argument"},{"level":3,"text":"Managing the Session","anchor":"managing-the-session","htmlText":"Managing the Session"},{"level":4,"text":"Flash Messages","anchor":"flash-messages","htmlText":"Flash Messages"},{"level":3,"text":"The Request and Response Object","anchor":"the-request-and-response-object","htmlText":"The Request and Response Object"},{"level":3,"text":"Final Thoughts","anchor":"final-thoughts","htmlText":"Final Thoughts"},{"level":3,"text":"Keep Going!","anchor":"keep-going","htmlText":"Keep Going!"},{"level":3,"text":"Learn more about Controllers","anchor":"learn-more-about-controllers","htmlText":"Learn more about Controllers"}],"lineInfo":{"truncatedLoc":"554","truncatedSloc":"392"},"mode":"file"},"image":false,"isCodeownersFile":null,"isPlain":false,"isValidLegacyIssueTemplate":false,"issueTemplate":null,"discussionTemplate":null,"language":"reStructuredText","languageID":419,"large":false,"planSupportInfo":{"repoIsFork":null,"repoOwnedByCurrentUser":null,"requestFullPath":"/symfony/symfony-docs/blob/3.0/controller.rst","showFreeOrgGatedFeatureMessage":null,"showPlanSupportBanner":null,"upgradeDataAttributes":null,"upgradePath":null},"publishBannersInfo":{"dismissActionNoticePath":"/settings/dismiss-notice/publish_action_from_dockerfile","releasePath":"/symfony/symfony-docs/releases/new?marketplace=true","showPublishActionBanner":false},"rawBlobUrl":"https://github.com/symfony/symfony-docs/raw/refs/heads/3.0/controller.rst","renderImageOrRaw":false,"richText":"\u003carticle class=\"markdown-body entry-content container-lg\" itemprop=\"text\"\u003e\u003cpre\u003e.. index::\n single: Controller\n\n\u003c/pre\u003e\n\u003ca name=\"user-content-controller\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eController\u003c/h2\u003e\u003ca id=\"user-content-controller\" class=\"anchor\" aria-label=\"Permalink: Controller\" href=\"#controller\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eA controller is a PHP function you create that reads information from the Symfony's\n\u003ccode\u003eRequest\u003c/code\u003e object and creates and returns a \u003ccode\u003eResponse\u003c/code\u003e object. The response could\nbe an HTML page, JSON, XML, a file download, a redirect, a 404 error or anything\nelse you can dream up. The controller executes whatever arbitrary logic\n\u003cem\u003eyour application\u003c/em\u003e needs to render the content of a page.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eSee how simple this is by looking at a Symfony controller in action.\nThis renders a page that prints a lucky (random) number:\u003c/p\u003e\n\u003cpre\u003e// src/AppBundle/Controller/LuckyController.php\nnamespace AppBundle\\Controller;\n\nuse Sensio\\Bundle\\FrameworkExtraBundle\\Configuration\\Route;\nuse Symfony\\Component\\HttpFoundation\\Response;\n\nclass LuckyController\n{\n /**\n * @Route(\"/lucky/number\")\n */\n public function numberAction()\n {\n $number = mt_rand(0, 100);\n\n return new Response(\n '\u0026lt;html\u0026gt;\u0026lt;body\u0026gt;Lucky number: '.$number.'\u0026lt;/body\u0026gt;\u0026lt;/html\u0026gt;'\n );\n }\n}\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eBut in the real world, your controller will probably do a lot of work in order to\ncreate the response. It might read information from the request, load a database\nresource, send an email or set information on the user's session.\nBut in all cases, the controller will eventually return the \u003ccode\u003eResponse\u003c/code\u003e object\nthat will be delivered back to the client.\u003c/p\u003e\n\u003cdiv dir=\"auto\"\u003e\n\u003cp dir=\"auto\"\u003eTip\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eIf you haven't already created your first working page, check out\n\u003ca href=\"#id1\"\u003e\u003cspan id=\"user-content-id2\"\u003e:doc:`/page_creation`\u003c/span\u003e\u003c/a\u003e and then come back!\u003c/p\u003e\n\u003c/div\u003e\n\u003cpre\u003e.. index::\n single: Controller; Simple example\n\n\u003c/pre\u003e\n\u003ca name=\"user-content-a-simple-controller\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eA Simple Controller\u003c/h3\u003e\u003ca id=\"user-content-a-simple-controller\" class=\"anchor\" aria-label=\"Permalink: A Simple Controller\" href=\"#a-simple-controller\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eWhile a controller can be any PHP callable (a function, method on an object,\nor a \u003ccode\u003eClosure\u003c/code\u003e), a controller is usually a method inside a controller\nclass:\u003c/p\u003e\n\u003cpre\u003e// src/AppBundle/Controller/LuckyController.php\nnamespace AppBundle\\Controller;\n\nuse Symfony\\Component\\HttpFoundation\\Response;\nuse Sensio\\Bundle\\FrameworkExtraBundle\\Configuration\\Route;\n\nclass LuckyController\n{\n /**\n * @Route(\"/lucky/number/{max}\")\n */\n public function numberAction($max)\n {\n $number = mt_rand(0, $max);\n\n return new Response(\n '\u0026lt;html\u0026gt;\u0026lt;body\u0026gt;Lucky number: '.$number.'\u0026lt;/body\u0026gt;\u0026lt;/html\u0026gt;'\n );\n }\n}\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eThe controller is the \u003ccode\u003enumberAction()\u003c/code\u003e method, which lives inside a\ncontroller class \u003ccode\u003eLuckyController\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThis controller is pretty straightforward:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003cem\u003eline 2\u003c/em\u003e: Symfony takes advantage of PHP's namespace functionality to\nnamespace the entire controller class.\u003c/li\u003e\n\u003cli\u003e\u003cem\u003eline 4\u003c/em\u003e: Symfony again takes advantage of PHP's namespace functionality:\nthe \u003ccode\u003euse\u003c/code\u003e keyword imports the \u003ccode\u003eResponse\u003c/code\u003e class, which the controller\nmust return.\u003c/li\u003e\n\u003cli\u003e\u003cem\u003eline 7\u003c/em\u003e: The class can technically be called anything - but should end in the\nword \u003ccode\u003eController\u003c/code\u003e (this isn't \u003cem\u003erequired\u003c/em\u003e, but some shortcuts rely on this).\u003c/li\u003e\n\u003cli\u003e\u003cem\u003eline 12\u003c/em\u003e: Each action method in a controller class is suffixed with \u003ccode\u003eAction\u003c/code\u003e\n(again, this isn't \u003cem\u003erequired\u003c/em\u003e, but some shortcuts rely on this). This method\nis allowed to have a \u003ccode\u003e$max\u003c/code\u003e argument thanks to the \u003ccode\u003e{max}\u003c/code\u003e\n\u003ca href=\"#id3\"\u003e\u003cspan id=\"user-content-id4\"\u003e:doc:`wildcard in the route \u0026lt;/routing\u0026gt;`\u003c/span\u003e\u003c/a\u003e.\u003c/li\u003e\n\u003cli\u003e\u003cem\u003eline 16\u003c/em\u003e: The controller creates and returns a \u003ccode\u003eResponse\u003c/code\u003e object.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cpre\u003e.. index::\n single: Controller; Routes and controllers\n\n\u003c/pre\u003e\n\u003ca name=\"user-content-mapping-a-url-to-a-controller\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eMapping a URL to a Controller\u003c/h4\u003e\u003ca id=\"user-content-mapping-a-url-to-a-controller\" class=\"anchor\" aria-label=\"Permalink: Mapping a URL to a Controller\" href=\"#mapping-a-url-to-a-controller\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eIn order to \u003cem\u003eview\u003c/em\u003e the result of this controller, you need to map a URL to it via\na route. This was done above with the \u003ccode\u003e@Route(\"/lucky/number/{max}\")\u003c/code\u003e annotation.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eTo see your page, go to this URL in your browser:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003ca href=\"http://localhost:8000/lucky/number/100\" rel=\"nofollow\"\u003ehttp://localhost:8000/lucky/number/100\u003c/a\u003e\u003c/blockquote\u003e\n\u003cp dir=\"auto\"\u003eFor more information on routing, see \u003ca href=\"#id5\"\u003e\u003cspan id=\"user-content-id6\"\u003e:doc:`/routing`\u003c/span\u003e\u003c/a\u003e.\u003c/p\u003e\n\u003cpre\u003e.. index::\n single: Controller; Base controller class\n\n\u003c/pre\u003e\n\u003ca name=\"user-content-the-base-controller-class-services\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eThe Base Controller Class \u0026amp; Services\u003c/h3\u003e\u003ca id=\"user-content-the-base-controller-class--services\" class=\"anchor\" aria-label=\"Permalink: The Base Controller Class \u0026amp; Services\" href=\"#the-base-controller-class--services\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eFor convenience, Symfony comes with an optional base\n\u003ca href=\"#id7\"\u003e\u003cspan id=\"user-content-id8\"\u003e:class:`Symfony\\\\Bundle\\\\FrameworkBundle\\\\Controller\\\\Controller`\u003c/span\u003e\u003c/a\u003e class.\nIf you extend it, this won't change anything about how your controller\nworks, but you'll get access to a number of \u003cstrong\u003ehelper methods\u003c/strong\u003e and the\n\u003cstrong\u003eservice container\u003c/strong\u003e (see \u003ca href=\"#id9\"\u003e\u003cspan id=\"user-content-id10\"\u003e:ref:`controller-accessing-services`\u003c/span\u003e\u003c/a\u003e): an\narray-like object that gives you access to every useful object in the\nsystem. These useful objects are called \u003cstrong\u003eservices\u003c/strong\u003e, and Symfony ships\nwith a service object that can render Twig templates, another that can\nlog messages and many more.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eAdd the \u003ccode\u003euse\u003c/code\u003e statement atop the \u003ccode\u003eController\u003c/code\u003e class and then modify\n\u003ccode\u003eLuckyController\u003c/code\u003e to extend it:\u003c/p\u003e\n\u003cpre\u003e// src/AppBundle/Controller/LuckyController.php\nnamespace AppBundle\\Controller;\n\nuse Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller;\n\nclass LuckyController extends Controller\n{\n // ...\n}\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eHelper methods are just shortcuts to using core Symfony functionality\nthat's available to you with or without the use of the base\n\u003ccode\u003eController\u003c/code\u003e class. A great way to see the core functionality in\naction is to look in the\n\u003ca href=\"#id11\"\u003e\u003cspan id=\"user-content-id12\"\u003e:class:`Symfony\\\\Bundle\\\\FrameworkBundle\\\\Controller\\\\Controller`\u003c/span\u003e\u003c/a\u003e class.\u003c/p\u003e\n\u003cpre\u003e.. index::\n single: Controller; Redirecting\n\n\u003c/pre\u003e\n\u003ca name=\"user-content-generating-urls\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eGenerating URLs\u003c/h4\u003e\u003ca id=\"user-content-generating-urls\" class=\"anchor\" aria-label=\"Permalink: Generating URLs\" href=\"#generating-urls\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe \u003ca href=\"#id13\"\u003e\u003cspan id=\"user-content-id14\"\u003e:method:`Symfony\\\\Bundle\\\\FrameworkBundle\\\\Controller\\\\Controller::generateUrl`\u003c/span\u003e\u003c/a\u003e\nmethod is just a helper method that generates the URL for a given route:\u003c/p\u003e\n\u003cpre\u003e$url = $this-\u0026gt;generateUrl('blog_show', array('slug' =\u0026gt; 'slug-value'));\n\u003c/pre\u003e\n\u003ca name=\"user-content-redirecting\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eRedirecting\u003c/h4\u003e\u003ca id=\"user-content-redirecting\" class=\"anchor\" aria-label=\"Permalink: Redirecting\" href=\"#redirecting\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eIf you want to redirect the user to another page, use the \u003ccode\u003eredirectToRoute()\u003c/code\u003e\nand \u003ccode\u003eredirect()\u003c/code\u003e methods:\u003c/p\u003e\n\u003cpre\u003epublic function indexAction()\n{\n // redirect to the \"homepage\" route\n return $this-\u0026gt;redirectToRoute('homepage');\n\n // do a permanent - 301 redirect\n return $this-\u0026gt;redirectToRoute('homepage', array(), 301);\n\n // redirect to a route with parameters\n return $this-\u0026gt;redirectToRoute('blog_show', array('slug' =\u0026gt; 'my-page'));\n\n // redirect externally\n return $this-\u0026gt;redirect('http://symfony.com/doc');\n}\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eFor more information, see the \u003ca href=\"#id15\"\u003e\u003cspan id=\"user-content-id16\"\u003e:doc:`Routing chapter \u0026lt;/routing\u0026gt;`\u003c/span\u003e\u003c/a\u003e.\u003c/p\u003e\n\u003cdiv dir=\"auto\"\u003e\n\u003cp dir=\"auto\"\u003eTip\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe \u003ccode\u003eredirectToRoute()\u003c/code\u003e method is simply a shortcut that creates a\n\u003ccode\u003eResponse\u003c/code\u003e object that specializes in redirecting the user. It's\nequivalent to:\u003c/p\u003e\n\u003cpre\u003euse Symfony\\Component\\HttpFoundation\\RedirectResponse;\n\npublic function indexAction()\n{\n return new RedirectResponse($this-\u0026gt;generateUrl('homepage'));\n}\n\u003c/pre\u003e\n\u003c/div\u003e\n\u003cpre\u003e.. index::\n single: Controller; Rendering templates\n\n\u003c/pre\u003e\n\u003ca name=\"user-content-rendering-templates\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eRendering Templates\u003c/h4\u003e\u003ca id=\"user-content-rendering-templates\" class=\"anchor\" aria-label=\"Permalink: Rendering Templates\" href=\"#rendering-templates\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eIf you're serving HTML, you'll want to render a template. The \u003ccode\u003erender()\u003c/code\u003e\nmethod renders a template \u003cstrong\u003eand\u003c/strong\u003e puts that content into a \u003ccode\u003eResponse\u003c/code\u003e\nobject for you:\u003c/p\u003e\n\u003cpre\u003e// renders app/Resources/views/lucky/number.html.twig\nreturn $this-\u0026gt;render('lucky/number.html.twig', array('name' =\u0026gt; $name));\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eTemplates can also live in deeper sub-directories. Just try to avoid\ncreating unnecessarily deep structures:\u003c/p\u003e\n\u003cpre\u003e// renders app/Resources/views/lottery/lucky/number.html.twig\nreturn $this-\u0026gt;render('lottery/lucky/number.html.twig', array(\n 'name' =\u0026gt; $name\n));\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eThe Symfony templating system and Twig are explained more in the\n\u003ca href=\"#id17\"\u003e\u003cspan id=\"user-content-id18\"\u003e:doc:`Creating and Using Templates chapter \u0026lt;/templating\u0026gt;`\u003c/span\u003e\u003c/a\u003e.\u003c/p\u003e\n\u003cpre\u003e.. index::\n single: Controller; Accessing services\n\n\u003c/pre\u003e\n\u003ca name=\"user-content-accessing-other-services\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eAccessing other Services\u003c/h4\u003e\u003ca id=\"user-content-accessing-other-services\" class=\"anchor\" aria-label=\"Permalink: Accessing other Services\" href=\"#accessing-other-services\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eSymfony comes packed with a lot of useful objects, called \u003cem\u003eservices\u003c/em\u003e. These\nare used for rendering templates, sending emails, querying the database and\nany other \"work\" you can think of. When you install a new bundle, it probably\nbrings in even \u003cem\u003emore\u003c/em\u003e services.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eWhen extending the base controller class, you can access any Symfony service\nvia the \u003ca href=\"#id19\"\u003e\u003cspan id=\"user-content-id20\"\u003e:method:`Symfony\\\\Bundle\\\\FrameworkBundle\\\\Controller\\\\Controller::get`\u003c/span\u003e\u003c/a\u003e\nmethod of the \u003ccode\u003eController\u003c/code\u003e class. Here are several common services you might\nneed:\u003c/p\u003e\n\u003cpre\u003e$templating = $this-\u0026gt;get('templating');\n\n$router = $this-\u0026gt;get('router');\n\n$mailer = $this-\u0026gt;get('mailer');\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eWhat other services exist? To list all services, use the \u003ccode\u003edebug:container\u003c/code\u003e\nconsole command:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"$ php bin/console debug:container\"\u003e\u003cpre\u003e$ php bin/console debug:container\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eFor more information, see the \u003ca href=\"#id21\"\u003e\u003cspan id=\"user-content-id22\"\u003e:doc:`/service_container`\u003c/span\u003e\u003c/a\u003e chapter.\u003c/p\u003e\n\u003cdiv dir=\"auto\"\u003e\n\u003cp dir=\"auto\"\u003eTip\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eTo get a \u003ca href=\"#id23\"\u003e\u003cspan id=\"user-content-id24\"\u003e:ref:`container configuration parameter \u0026lt;config-parameter-intro\u0026gt;`\u003c/span\u003e\u003c/a\u003e,\nuse the\n\u003ca href=\"#id25\"\u003e\u003cspan id=\"user-content-id26\"\u003e:method:`Symfony\\\\Bundle\\\\FrameworkBundle\\\\Controller\\\\Controller::getParameter`\u003c/span\u003e\u003c/a\u003e\nmethod:\u003c/p\u003e\n\u003cpre\u003e$from = $this-\u0026gt;getParameter('app.mailer.from');\n\u003c/pre\u003e\n\u003c/div\u003e\n\u003cpre\u003e.. index::\n single: Controller; Managing errors\n single: Controller; 404 pages\n\n\u003c/pre\u003e\n\u003ca name=\"user-content-managing-errors-and-404-pages\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eManaging Errors and 404 Pages\u003c/h3\u003e\u003ca id=\"user-content-managing-errors-and-404-pages\" class=\"anchor\" aria-label=\"Permalink: Managing Errors and 404 Pages\" href=\"#managing-errors-and-404-pages\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1
8784
.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eWhen things are not found, you should play well with the HTTP protocol and\nreturn a 404 response. To do this, you'll throw a special type of exception.\nIf you're extending the base \u003ccode\u003eController\u003c/code\u003e class, do the following:\u003c/p\u003e\n\u003cpre\u003epublic function indexAction()\n{\n // retrieve the object from database\n $product = ...;\n if (!$product) {\n throw $this-\u0026gt;createNotFoundException('The product does not exist');\n }\n\n return $this-\u0026gt;render(...);\n}\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eThe \u003ca href=\"#id27\"\u003e\u003cspan id=\"user-content-id28\"\u003e:method:`Symfony\\\\Bundle\\\\FrameworkBundle\\\\Controller\\\\Controller::createNotFoundException`\u003c/span\u003e\u003c/a\u003e\nmethod is just a shortcut to create a special\n\u003ca href=\"#id29\"\u003e\u003cspan id=\"user-content-id30\"\u003e:class:`Symfony\\\\Component\\\\HttpKernel\\\\Exception\\\\NotFoundHttpException`\u003c/span\u003e\u003c/a\u003e\nobject, which ultimately triggers a 404 HTTP response inside Symfony.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eOf course, you're free to throw any \u003ccode\u003eException\u003c/code\u003e class in your controller -\nSymfony will automatically return a 500 HTTP response code.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-text-html-php notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"throw new \\Exception('Something went wrong!');\"\u003e\u003cpre\u003e\u003cspan class=\"pl-k\"\u003ethrow\u003c/span\u003e \u003cspan class=\"pl-k\"\u003enew\u003c/span\u003e \\\u003cspan class=\"pl-v\"\u003eException\u003c/span\u003e(\u003cspan class=\"pl-s\"\u003e'\u003cspan class=\"pl-s\"\u003eSomething went wrong!\u003c/span\u003e'\u003c/span\u003e);\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eIn every case, an error page is shown to the end user and a full debug\nerror page is shown to the developer (i.e. when you're using the \u003ccode\u003eapp_dev.php\u003c/code\u003e\nfront controller - see \u003ca href=\"#id31\"\u003e\u003cspan id=\"user-content-id32\"\u003e:ref:`page-creation-environments`\u003c/span\u003e\u003c/a\u003e).\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eYou'll want to customize the error page your user sees. To do that, see\nthe \u003ca href=\"#id33\"\u003e\u003cspan id=\"user-content-id34\"\u003e:doc:`/controller/error_pages`\u003c/span\u003e\u003c/a\u003e article.\u003c/p\u003e\n\u003cpre\u003e.. index::\n single: Controller; The session\n single: Session\n\n\u003c/pre\u003e\n\u003ca name=\"user-content-the-request-object-as-a-controller-argument\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eThe Request object as a Controller Argument\u003c/h3\u003e\u003ca id=\"user-content-the-request-object-as-a-controller-argument\" class=\"anchor\" aria-label=\"Permalink: The Request object as a Controller Argument\" href=\"#the-request-object-as-a-controller-argument\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eWhat if you need to read query parameters, grab a request header or get access\nto an uploaded file? All of that information is stored in Symfony's \u003ccode\u003eRequest\u003c/code\u003e\nobject. To get it in your controller, just add it as an argument and\n\u003cstrong\u003etype-hint it with the Request class\u003c/strong\u003e:\u003c/p\u003e\n\u003cpre\u003euse Symfony\\Component\\HttpFoundation\\Request;\n\npublic function indexAction($firstName, $lastName, Request $request)\n{\n $page = $request-\u0026gt;query-\u0026gt;get('page', 1);\n\n // ...\n}\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003e\u003ca href=\"#id35\"\u003e\u003cspan id=\"user-content-id36\"\u003e:ref:`Keep reading \u0026lt;request-object-info\u0026gt;`\u003c/span\u003e\u003c/a\u003e for more information about using the\nRequest object.\u003c/p\u003e\n\u003ca name=\"user-content-managing-the-session\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eManaging the Session\u003c/h3\u003e\u003ca id=\"user-content-managing-the-session\" class=\"anchor\" aria-label=\"Permalink: Managing the Session\" href=\"#managing-the-session\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eSymfony provides a nice session object that you can use to store information\nabout the user between requests. By default, Symfony stores the attributes in a\ncookie by using native PHP sessions.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eTo retrieve the session, call\n\u003ca href=\"#id37\"\u003e\u003cspan id=\"user-content-id38\"\u003e:method:`Symfony\\\\Bundle\\\\FrameworkBundle\\\\Controller\\\\Controller::getSession`\u003c/span\u003e\u003c/a\u003e\nmethod on the \u003ccode\u003eRequest\u003c/code\u003e object. This method returns a\n\u003ca href=\"#id39\"\u003e\u003cspan id=\"user-content-id40\"\u003e:class:`Symfony\\\\Component\\\\HttpFoundation\\\\Session\\\\SessionInterface`\u003c/span\u003e\u003c/a\u003e with easy\nmethods for storing and fetching things from the session:\u003c/p\u003e\n\u003cpre\u003euse Symfony\\Component\\HttpFoundation\\Request;\n\npublic function indexAction(Request $request)\n{\n $session = $request-\u0026gt;getSession();\n\n // store an attribute for reuse during a later user request\n $session-\u0026gt;set('foo', 'bar');\n\n // get the attribute set by another controller in another request\n $foobar = $session-\u0026gt;get('foobar');\n\n // use a default value if the attribute doesn't exist\n $filters = $session-\u0026gt;get('filters', array());\n}\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eStored attributes remain in the session for the remainder of that user's session.\u003c/p\u003e\n\u003cpre\u003e.. index::\n single: Session; Flash messages\n\n\u003c/pre\u003e\n\u003ca name=\"user-content-flash-messages\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eFlash Messages\u003c/h4\u003e\u003ca id=\"user-content-flash-messages\" class=\"anchor\" aria-label=\"Permalink: Flash Messages\" href=\"#flash-messages\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eYou can also store special messages, called \"flash\" messages, on the user's\nsession. By design, flash messages are meant to be used exactly once: they vanish\nfrom the session automatically as soon as you retrieve them. This feature makes\n\"flash\" messages particularly great for storing user notifications.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eFor example, imagine you're processing a \u003ca href=\"#id41\"\u003e\u003cspan id=\"user-content-id42\"\u003e:doc:`form \u0026lt;/forms\u0026gt;`\u003c/span\u003e\u003c/a\u003e submission:\u003c/p\u003e\n\u003cpre\u003euse Symfony\\Component\\HttpFoundation\\Request;\n\npublic function updateAction(Request $request)\n{\n // ...\n\n if ($form-\u0026gt;isValid()) {\n // do some sort of processing\n\n $this-\u0026gt;addFlash(\n 'notice',\n 'Your changes were saved!'\n );\n // $this-\u0026gt;addFlash is equivalent to $request-\u0026gt;getSession()-\u0026gt;getFlashBag()-\u0026gt;add\n\n return $this-\u0026gt;redirectToRoute(...);\n }\n\n return $this-\u0026gt;render(...);\n}\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eAfter processing the request, the controller sets a flash message in the session\nand then redirects. The message key (\u003ccode\u003enotice\u003c/code\u003e in this example) can be anything:\nyou'll use this key to retrieve the message.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eIn the template of the next page (or even better, in your base layout template),\nread any flash messages from the session:\u003c/p\u003e\n\u003cpre\u003e.. configuration-block::\n\n .. code-block:: html+twig\n\n {# app/Resources/views/base.html.twig #}\n {% for flash_message in app.session.flashBag.get('notice') %}\n \u0026lt;div class=\"flash-notice\"\u0026gt;\n {{ flash_message }}\n \u0026lt;/div\u0026gt;\n {% endfor %}\n\n .. code-block:: html+php\n\n \u0026lt;!-- app/Resources/views/base.html.php --\u0026gt;\n \u0026lt;?php foreach ($view['session']-\u0026gt;getFlash('notice') as $message): ?\u0026gt;\n \u0026lt;div class=\"flash-notice\"\u0026gt;\n \u0026lt;?php echo \"\u0026lt;div class='flash-error'\u0026gt;$message\u0026lt;/div\u0026gt;\" ?\u0026gt;\n \u0026lt;/div\u0026gt;\n \u0026lt;?php endforeach ?\u0026gt;\n\n\u003c/pre\u003e\n\u003cdiv dir=\"auto\"\u003e\n\u003cp dir=\"auto\"\u003eNote\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eIt's common to use \u003ccode\u003enotice\u003c/code\u003e, \u003ccode\u003ewarning\u003c/code\u003e and \u003ccode\u003eerror\u003c/code\u003e as the keys of the\ndifferent types of flash messages, but you can use any key that fits your\nneeds.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv dir=\"auto\"\u003e\n\u003cp dir=\"auto\"\u003eTip\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eYou can use the\n\u003ca href=\"#id43\"\u003e\u003cspan id=\"user-content-id44\"\u003e:method:`Symfony\\\\Component\\\\HttpFoundation\\\\Session\\\\Flash\\\\FlashBagInterface::peek`\u003c/span\u003e\u003c/a\u003e\nmethod instead to retrieve the message while keeping it in the bag.\u003c/p\u003e\n\u003c/div\u003e\n\u003cpre\u003e.. index::\n single: Controller; Response object\n\n\u003c/pre\u003e\n\u003ca name=\"user-content-the-request-and-response-object\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eThe Request and Response Object\u003c/h3\u003e\u003ca id=\"user-content-the-request-and-response-object\" class=\"anchor\" aria-label=\"Permalink: The Request and Response Object\" href=\"#the-request-and-response-object\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eAs mentioned \u003ca href=\"#id45\"\u003e\u003cspan id=\"user-content-id46\"\u003e:ref:`earlier \u0026lt;controller-request-argument\u0026gt;`\u003c/span\u003e\u003c/a\u003e, the framework will\npass the \u003ccode\u003eRequest\u003c/code\u003e object to any controller argument that is type-hinted with\nthe \u003ccode\u003eRequest\u003c/code\u003e class:\u003c/p\u003e\n\u003cpre\u003euse Symfony\\Component\\HttpFoundation\\Request;\n\npublic function indexAction(Request $request)\n{\n $request-\u0026gt;isXmlHttpRequest(); // is it an Ajax request?\n\n $request-\u0026gt;getPreferredLanguage(array('en', 'fr'));\n\n // retrieve GET and POST variables respectively\n $request-\u0026gt;query-\u0026gt;get('page');\n $request-\u0026gt;request-\u0026gt;get('page');\n\n // retrieve SERVER variables\n $request-\u0026gt;server-\u0026gt;get('HTTP_HOST');\n\n // retrieves an instance of UploadedFile identified by foo\n $request-\u0026gt;files-\u0026gt;get('foo');\n\n // retrieve a COOKIE value\n $request-\u0026gt;cookies-\u0026gt;get('PHPSESSID');\n\n // retrieve an HTTP request header, with normalized, lowercase keys\n $request-\u0026gt;headers-\u0026gt;get('host');\n $request-\u0026gt;headers-\u0026gt;get('content_type');\n}\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eThe \u003ccode\u003eRequest\u003c/code\u003e class has several public properties and methods that return any\ninformation you need about the request.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eLike the \u003ccode\u003eRequest\u003c/code\u003e, the \u003ccode\u003eResponse\u003c/code\u003e object has also a public \u003ccode\u003eheaders\u003c/code\u003e property.\nThis is a \u003ca href=\"#id47\"\u003e\u003cspan id=\"user-content-id48\"\u003e:class:`Symfony\\\\Component\\\\HttpFoundation\\\\ResponseHeaderBag`\u003c/span\u003e\u003c/a\u003e that has\nsome nice methods for getting and setting response headers. The header names are\nnormalized so that using \u003ccode\u003eContent-Type\u003c/code\u003e is equivalent to \u003ccode\u003econtent-type\u003c/code\u003e or even\n\u003ccode\u003econtent_type\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe only requirement for a controller is to return a \u003ccode\u003eResponse\u003c/code\u003e object.\nThe \u003ca href=\"#id49\"\u003e\u003cspan id=\"user-content-id50\"\u003e:class:`Symfony\\\\Component\\\\HttpFoundation\\\\Response`\u003c/span\u003e\u003c/a\u003e class is an\nabstraction around the HTTP response - the text-based message filled with\nheaders and content that's sent back to the client:\u003c/p\u003e\n\u003cpre\u003euse Symfony\\Component\\HttpFoundation\\Response;\n\n// create a simple Response with a 200 status code (the default)\n$response = new Response('Hello '.$name, Response::HTTP_OK);\n\n// JsonResponse is a sub-class of Response\n$response = new JsonResponse(array('name' =\u0026gt; $name));\n// set a header!\n$response-\u0026gt;headers-\u0026gt;set('X-Rate-Limit', 10);\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eThere are special classes that make certain kinds of responses easier:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eFor JSON, there is \u003ca href=\"#id51\"\u003e\u003cspan id=\"user-content-id52\"\u003e:class:`Symfony\\\\Component\\\\HttpFoundation\\\\JsonResponse`\u003c/span\u003e\u003c/a\u003e.\nSee \u003ca href=\"#id53\"\u003e\u003cspan id=\"user-content-id54\"\u003e:ref:`component-http-foundation-json-response`\u003c/span\u003e\u003c/a\u003e.\u003c/li\u003e\n\u003cli\u003eFor files, there is \u003ca href=\"#id55\"\u003e\u003cspan id=\"user-content-id56\"\u003e:class:`Symfony\\\\Component\\\\HttpFoundation\\\\BinaryFileResponse`\u003c/span\u003e\u003c/a\u003e.\nSee \u003ca href=\"#id57\"\u003e\u003cspan id=\"user-content-id58\"\u003e:ref:`component-http-foundation-serving-files`\u003c/span\u003e\u003c/a\u003e.\u003c/li\u003e\n\u003cli\u003eFor streamed responses, there is\n\u003ca href=\"#id59\"\u003e\u003cspan id=\"user-content-id60\"\u003e:class:`Symfony\\\\Component\\\\HttpFoundation\\\\StreamedResponse`\u003c/span\u003e\u003c/a\u003e.\nSee \u003ca href=\"#id61\"\u003e\u003cspan id=\"user-content-id62\"\u003e:ref:`streaming-response`\u003c/span\u003e\u003c/a\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cpre\u003e.. seealso::\n\n Now that you know the basics you can continue your research on Symfony\n ``Request`` and ``Response`` object in the\n :ref:`HttpFoundation component documentation \u0026lt;component-http-foundation-request\u0026gt;`.\n\n\u003c/pre\u003e\n\u003ca name=\"user-content-final-thoughts\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eFinal Thoughts\u003c/h3\u003e\u003ca id=\"user-content-final-thoughts\" class=\"anchor\" aria-label=\"Permalink: Final Thoughts\" href=\"#final-thoughts\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eWhenever you create a page, you'll ultimately need to write some code that\ncontains the logic for that page. In Symfony, this is called a controller,\nand it's a PHP function where you can do anything in order to return the\nfinal \u003ccode\u003eResponse\u003c/code\u003e object that will be returned to the user.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eTo make life easier, you'll probably extend the base \u003ccode\u003eController\u003c/code\u003e class because\nthis gives two things:\u003c/p\u003e\n\u003col dir=\"auto\"\u003e\n\u003cli\u003eShortcut methods (like \u003ccode\u003erender()\u003c/code\u003e and \u003ccode\u003eredirectToRoute\u003c/code\u003e);\u003c/li\u003e\n\u003cli\u003eAccess to \u003cem\u003eall\u003c/em\u003e of the useful objects (services) in the system via the\n\u003ca href=\"#id63\"\u003e\u003cspan id=\"user-content-id64\"\u003e:ref:`get() \u0026lt;controller-accessing-services\u0026gt;`\u003c/span\u003e\u003c/a\u003e method.\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp dir=\"auto\"\u003eIn other chapters, you'll learn how to use specific services from inside your controller\nthat will help you persist and fetch objects from a database, process form submissions,\nhandle caching and more.\u003c/p\u003e\n\u003ca name=\"user-content-keep-going\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eKeep Going!\u003c/h3\u003e\u003ca id=\"user-content-keep-going\" class=\"anchor\" aria-label=\"Permalink: Keep Going!\" href=\"#keep-going\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eNext, learn all about \u003ca href=\"#id65\"\u003e\u003cspan id=\"user-content-id66\"\u003e:doc:`rendering templates with Twig \u0026lt;/templating\u0026gt;`\u003c/span\u003e\u003c/a\u003e.\u003c/p\u003e\n\u003ca name=\"user-content-learn-more-about-controllers\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eLearn more about Controllers\u003c/h3\u003e\u003ca id=\"user-content-learn-more-about-controllers\" class=\"anchor\" aria-label=\"Permalink: Learn more about Controllers\" href=\"#learn-more-about-controllers\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cpre\u003e.. toctree::\n :hidden:\n\n templating\n\n\u003c/pre\u003e\n\u003cpre\u003e.. toctree::\n :maxdepth: 1\n :glob:\n\n controller/*\n\u003c/pre\u003e\n\n\u003c/article\u003e","renderedFileInfo":null,"shortPath":null,"symbolsEnabled":true,"tabSize":2,"topBannersInfo":{"overridingGlobalFundingFile":false,"globalPreferredFundingPath":"/symfony/.github/blob/6f2ca452c856184a28812bb364b4e34ed50309da/FUNDING.yml","showInvalidCitationWarning":false,"citationHelpUrl":"https://docs.github.com/github/creating-cloning-and-archiving-repositories/creating-a-repository-on-github/about-citation-files","actionsOnboardingTip":null},"truncated":false,"viewable":true,"workflowRedirectUrl":null,"symbols":null},"copilotInfo":null,"copilotAccessAllowed":false,"modelsAccessAllowed":false,"modelsRepoIntegrationEnabled":false,"csrf_tokens":{"/symfony/symfony-docs/branches":{"post":"iDUvp7PxGV6tz9S28dG1AJPdNxHMCXCe5f05n7aEttYPxu7Cfm-D11ogx8tTnaiavtMLs8JrwRJQZC3zHsz-6w"},"/repos/preferences":{"post":"xDIzw0_canxUAeRVSxTZfs8J9cWL1ccyIceOtHXwpBtGo2bB_xOoHfUcMGORWR7G95oniwUMD7Q1rCVOuvaLow"}}},"title":"symfony-docs/controller.rst at 3.0 · symfony/symfony-docs","appPayload":{"helpUrl":"https://docs.github.com","findFileWorkerPath":"/assets-cdn/worker/find-file-worker-263cab1760dd.js","findInFileWorkerPath":"/assets-cdn/worker/find-in-file-worker-b84e9496fc59.js","githubDevUrl":null,"enabled_features":{"code_nav_ui_events":false,"react_blob_overlay":false,"accessible_code_button":true}}}