8000 symfony-docs/controller.rst at 3.0 · symfony/symfony-docs · GitHub
[go: up one dir, main page]

Skip to content
{"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}}}
0