8000 symfony-docs/controller.rst at 4.3 · 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":".symfony","path":".symfony","contentType":"directory"},{"name":"_build","path":"_build","contentType":"directory"},{"name":"_images","path":"_images","contentType":"directory"},{"name":"_includes","path":"_includes","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":"deployment","path":"deployment","contentType":"directory"},{"name":"doctrine","path":"doctrine","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":"messenger","path":"messenger","contentType":"directory"},{"name":"profiler","path":"profiler","contentType":"directory"},{"name":"quick_tour","path":"quick_tour","contentType":"directory"},{"name":"reference","path":"reference","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":"workflow","path":"workflow","contentType":"directory"},{"name":".doctor-rst.yaml","path":".doctor-rst.yaml","contentType":"file"},{"name":".editorconfig","path":".editorconfig","contentType":"file"},{"name":".gitignore","path":".gitignore","contentType":"file"},{"name":".symfony.cloud.yaml","path":".symfony.cloud.yaml","contentType":"file"},{"name":".travis.yml","path":".travis.yml","contentType":"file"},{"name":"CODE_OF_CONDUCT.md","path":"CODE_OF_CONDUCT.md","contentType":"file"},{"name":"Dockerfile","path":"Dockerfile","contentType":"file"},{"name":"LICENSE.md","path":"LICENSE.md","contentType":"file"},{"name":"README.markdown","path":"README.markdown","contentType":"file"},{"name":"best_practices.rst","path":"best_practices.rst","contentType":"file"},{"name":"bundles.rst","path":"bundles.rst","contentType":"file"},{"name":"cache.rst","path":"cache.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":"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":"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":"mailer.rst","path":"mailer.rst","contentType":"file"},{"name":"mercure.rst","path":"mercure.rst","contentType":"file"},{"name":"messenger.rst","path":"messenger.rst","contentType":"file"},{"name":"migration.rst","path":"migration.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":"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":"templates.rst","path":"templates.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"},{"name":"web_link.rst","path":"web_link.rst","contentType":"file"},{"name":"workflow.rst","path":"workflow.rst","contentType":"file"}],"totalCount":79}},"fileTreeProcessingTime":12.346558,"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":"4.3","listCacheKey":"v0:1751870253.0","canEdit":false,"refType":"branch","currentOid":"96723ac04ad7d73ed50f24d3f4a688c5a857934f"},"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/4.3/controller.rst?raw=true","headerInfo":{"blobSize":"20.9 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":"879c984","siteNavLoginPath":"/login?return_to=https%3A%2F%2Fgithub.com%2Fsymfony%2Fsymfony-docs%2Fblob%2F4.3%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":"Fetching Services","anchor":"fetching-services","htmlText":"Fetching Services"},{"level":3,"text":"Generating Controllers","anchor":"generating-controllers","htmlText":"Generating Controllers"},{"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":4,"text":"Accessing Configuration Values","anchor":"accessing-configuration-values","htmlText":"Accessing Configuration Values"},{"level":4,"text":"Returning JSON Response","anchor":"returning-json-response","htmlText":"Returning JSON Response"},{"level":4,"text":"Streaming File Responses","anchor":"streaming-file-responses","htmlText":"Streaming File Responses"},{"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":"671","truncatedSloc":"479"},"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/4.3/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/4.3/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\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. The controller executes whatever arbitrary logic \u003cem\u003eyour application\u003c/em\u003e needs\nto render the content of a page.\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 (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/Controller/LuckyController.php\nnamespace App\\Controller;\n\nuse Symfony\\Component\\HttpFoundation\\Response;\nuse Symfony\\Component\\Routing\\Annotation\\Route;\n\nclass LuckyController\n{\n /**\n * @Route(\"/lucky/number/{max}\", name=\"app_lucky_number\")\n */\n public function number($max)\n {\n $number = random_int(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\u003enumber()\u003c/code\u003e method, which lives inside the\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 it's suffixed\nwith \u003ccode\u003eController\u003c/code\u003e by convention.\u003c/li\u003e\n\u003cli\u003e\u003cem\u003eline 12\u003c/em\u003e: The action method is allowed to have a \u003ccode\u003e$max\u003c/code\u003e argument thanks to the\n\u003ccode\u003e{max}\u003c/code\u003e \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\n\u003ca href=\"#id5\"\u003e\u003cspan id=\"user-content-id6\"\u003e:ref:`route annotation \u0026lt;annotation-routes\u0026gt;`\u003c/span\u003e\u003c/a\u003e.\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=\"#id7\"\u003e\u003cspan id=\"user-content-id8\"\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-id9\"\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\"\u003eTo aid development, Symfony comes with an optional base controller class called\n\u003ca href=\"#id10\"\u003e\u003cspan id=\"user-content-id11\"\u003e:class:`Symfony\\\\Bundle\\\\FrameworkBundle\\\\Controller\\\\AbstractController`\u003c/span\u003e\u003c/a\u003e.\nIt can be extended to gain access to helper methods.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eAdd the \u003ccode\u003euse\u003c/code\u003e statement atop your controller class and then modify\n\u003ccode\u003eLuckyController\u003c/code\u003e to extend it:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-diff notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"// src/Controller/LuckyController.php\nnamespace App\\Controller;\n\n+ use Symfony\\Bundle\\FrameworkBundle\\Controller\\AbstractController;\n\n- class LuckyController\n+ class LuckyController extends AbstractController\n{\n // ...\n}\"\u003e\u003cpre\u003e// src/Controller/LuckyController.php\nnamespace App\\Controller;\n\n\u003cspan class=\"pl-mi1\"\u003e\u003cspan class=\"pl-mi1\"\u003e+\u003c/span\u003e use Symfony\\Bundle\\FrameworkBundle\\Controller\\AbstractController;\u003c/span\u003e\n\n\u003cspan class=\"pl-md\"\u003e\u003cspan class=\"pl-md\"\u003e-\u003c/span\u003e class LuckyController\u003c/span\u003e\n\u003cspan class=\"pl-mi1\"\u003e\u003cspan class=\"pl-mi1\"\u003e+\u003c/span\u003e class LuckyController extends AbstractController\u003c/span\u003e\n{\n // ...\n}\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThat's it! You now have access to methods like \u003ca href=\"#id12\"\u003e\u003cspan id=\"user-content-id13\"\u003e:ref:`$this-\u0026gt;render() \u0026lt;controller-rendering-templates\u0026gt;`\u003c/span\u003e\u003c/a\u003e\nand many others that you'll learn about next.\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=\"#id14\"\u003e\u003cspan id=\"user-content-id15\"\u003e:method:`Symfony\\\\Bundle\\\\FrameworkBundle\\\\Controller\\\\AbstractController::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('app_lucky_number', ['max' =\u0026gt; 10]);\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\u003euse Symfony\\Component\\HttpFoundation\\RedirectResponse;\n\n// ...\npublic function index()\n{\n // redirects to the \"homepage\" route\n return $this-\u0026gt;redirectToRoute('homepage');\n\n // redirectToRoute is a shortcut for:\n // return new RedirectResponse($this-\u0026gt;generateUrl('homepage'));\n\n // does a permanent - 301 redirect\n return $this-\u0026gt;redirectToRoute('homepage', [], 301);\n\n // redirect to a route with parameters\n return $this-\u0026gt;redirectToRoute('app_lucky_number', ['max' =\u0026gt; 10]);\n\n // redirects to a route and maintains the original query string parameters\n return $this-\u0026gt;redirectToRoute('blog_show', $request-\u0026gt;query-\u0026gt;all());\n\n // redirects externally\n return $this-\u0026gt;redirect('http://symfony.com/doc');\n}\n\u003c/pre\u003e\n\u003cdiv dir=\"auto\"\u003e\n\u003cp dir=\"auto\"\u003eCaution!\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe \u003ccode\u003eredirect()\u003c/code\u003e method does not check its destination in any way. If you\nredirect to a URL provided by end-users, your application may be open\nto the \u003ca href=\"https://www.owasp.org/index.php/Open_redirect\" rel=\"nofollow\"\u003eunvalidated redirects security vulnerability\u003c/a\u003e.\u003c/p\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 templates/lucky/number.html.twig\nreturn $this-\u0026gt;render('lucky/number.html.twig', ['number' =\u0026gt; $number]);\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eTemplating and Twig are explained more in the\n\u003ca href=\"#id16\"\u003e\u003cspan id=\"user-content-id17\"\u003e:doc:`Creating and Using Templates article \u0026lt;/templates\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-fetching-services\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eFetching Services\u003c/h4\u003e\u003ca id=\"user-content-fetching-services\" class=\"anchor\" aria-label=\"Permalink: Fetching Services\" href=\"#fetching-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 \u003cem\u003epacked\u003c/em\u003e with a lot of useful objects, called \u003ca href=\"#id18\"\u003e\u003cspan id=\"user-content-id19\"\u003e:doc:`services \u0026lt;/service_container\u0026gt;`\u003c/span\u003e\u003c/a\u003e.\nThese are used for rendering templates, sending emails, querying the database and\nany other \"work\" you can think of.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eIf you need a service in a controller, type-hint an argument with its class\n(or interface) name. Symfony will automatically pass you the service you need:\u003c/p\u003e\n\u003cpre\u003euse Psr\\Log\\LoggerInterface;\n// ...\n\n/**\n * @Route(\"/lucky/number/{max}\")\n */\npublic function number($max, LoggerInterface $logger)\n{\n $logger-\u0026gt;info('We are logging!');\n // ...\n}\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eAwesome!\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eWhat other services can you type-hint? To see them, use the \u003ccode\u003edebug:autowiring\u003c/code\u003e console\ncommand:\u003c/p\u003e\n\u003cpre lang=\"terminal\"\u003e$ php bin/console debug:autowiring\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eIf you need control over the \u003cem\u003eexact\u003c/em\u003e value of an argument, you can \u003ca href=\"#id20\"\u003e\u003cspan id=\"user-content-id21\"\u003e:ref:`bind \u0026lt;services-binding\u0026gt;`\u003c/span\u003e\u003c/a\u003e\nthe argument by its name:\u003c/p\u003e\n\u003cpre\u003e.. configuration-block::\n\n .. code-block:: yaml\n\n # config/services.yaml\n services:\n # ...\n\n # explicitly configure the service\n App\\Controller\\LuckyController:\n public: true\n bind:\n # for any $logger argument, pass this specific service\n $logger: '@monolog.logger.doctrine'\n # for any $projectDir argument, pass this parameter value\n $projectDir: '%kernel.project_dir%'\n\n .. code-block:: xml\n\n \u0026lt;!-- config/services.xml --\u0026gt;\n \u0026lt;?xml version=\"1.0\" encoding=\"UTF-8\" ?\u0026gt;\n \u0026lt;container xmlns=\"http://symfony.com/schema/dic/services\"\n xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n xsi:schemaLocation=\"http://symfony.com/schema/dic/services\n https://symfony.com/schema/dic/services/services-1.0.xsd\"\u0026gt;\n\n \u0026lt;services\u0026gt;\n \u0026lt;!-- ... --\u0026gt;\n\n \u0026lt;!-- Explicitly configure the service --\u0026gt;\n \u0026lt;service id=\"App\\Controller\\LuckyController\" public=\"true\"\u0026gt;\n \u0026lt;bind key=\"$logger\"\n type=\"service\"\n id=\"monolog.logger.doctrine\"\n /\u0026gt;\n \u0026lt;bind key=\"$projectDir\"\u0026gt;%kernel.project_dir%\u0026lt;/bind\u0026gt;\n \u0026lt;/service\u0026gt;\n \u0026lt;/services\u0026gt;\n \u0026lt;/container\u0026gt;\n\n .. code-block:: php\n\n // config/services.php\n use App\\Controller\\LuckyController;\n use Symfony\\Component\\DependencyInjection\\Reference;\n\n $container-\u0026gt;register(LuckyController::class)\n -\u0026gt;setPublic(true)\n -\u0026gt;setBindings([\n '$logger' =\u0026gt; new Reference('monolog.logger.doctrine'),\n '$projectDir' =\u0026gt; '%kernel.project_dir%'\n ])\n ;\n\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eLike with all services, you can also use regular \u003ca href=\"#id22\"\u003e\u003cspan id=\"user-content-id23\"\u003e:ref:`constructor injection \u0026lt;services-constructor-injection\u0026gt;`\u003c/span\u003e\u003c/a\u003e\nin your controllers.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eFor more information about services, see the \u003ca href=\"#id24\"\u003e\u003cspan id=\"user-content-id25\"\u003e:doc:`/service_container`\u003c/span\u003e\u003c/a\u003e article.\u003c/p\u003e\n\u003ca name=\"user-content-generating-controllers\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003e 8000 Generating Controllers\u003c/h3\u003e\u003ca id=\"user-content-generating-controllers\" class=\"anchor\" aria-label=\"Permalink: Generating Controllers\" href=\"#generating-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\u003cp dir=\"auto\"\u003eTo save time, you can install \u003ca href=\"https://symfony.com/doc/current/bundles/SymfonyMakerBundle/index.html\" rel=\"nofollow\"\u003eSymfony Maker\u003c/a\u003e and tell Symfony to generate a\nnew controller class:\u003c/p\u003e\n\u003cpre lang=\"terminal\"\u003e$ php bin/console make:controller BrandNewController\n\ncreated: src/Controller/BrandNewController.php\ncreated: templates/brandnew/index.html.twig\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eIf you want to generate an entire CRUD from a Doctrine \u003ca href=\"#id26\"\u003e\u003cspan id=\"user-content-id27\"\u003e:doc:`entity \u0026lt;/doctrine\u0026gt;`\u003c/span\u003e\u003c/a\u003e,\nuse:\u003c/p\u003e\n\u003cpre lang=\"terminal\"\u003e$ php bin/console make:crud Product\n\ncreated: src/Controller/ProductController.php\ncreated: src/Form/ProductType.php\ncreated: templates/product/_delete_form.html.twig\ncreated: templates/product/_form.html.twig\ncreated: templates/product/edit.html.twig\ncreated: templates/product/index.html.twig\ncreated: templates/product/new.html.twig\ncreated: templates/product/show.html.twig\n\u003c/pre\u003e\n\u003cpre\u003e.. versionadded:: 1.2\n\n The ``make:crud`` command was introduced in MakerBundle 1.2.\n\n\u003c/pre\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.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 return a 404 response. To do this, throw a\nspecial type of exception:\u003c/p\u003e\n\u003cpre\u003euse Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException;\n\n// ...\npublic function index()\n{\n // retrieve the object from database\n $product = ...;\n if (!$product) {\n throw $this-\u0026gt;createNotFoundException('The product does not exist');\n\n // the above is just a shortcut for:\n // throw new NotFoundHttpException('The product does not exist');\n }\n\n return $this-\u0026gt;render(...);\n}\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eThe \u003ca href=\"#id28\"\u003e\u003cspan id=\"user-content-id29\"\u003e:method:`Symfony\\\\Bundle\\\\FrameworkBundle\\\\Controller\\\\AbstractController::createNotFoundException`\u003c/span\u003e\u003c/a\u003e\nmethod is just a shortcut to create a special\n\u003ca href=\"#id30\"\u003e\u003cspan id=\"user-content-id31\"\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\"\u003eIf you throw an exception that extends or is an instance of\n\u003ca href=\"#id32\"\u003e\u003cspan id=\"user-content-id33\"\u003e:class:`Symfony\\\\Component\\\\HttpKernel\\\\Exception\\\\HttpException`\u003c/span\u003e\u003c/a\u003e, Symfony will\nuse the appropriate HTTP status code. Otherwise, the response will have a 500\nHTTP status code:\u003c/p\u003e\n\u003cpre\u003e// this exception ultimately generates a 500 status error\nthrow new \\Exception('Something went wrong!');\n\u003c/pre\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 in \"Debug\" mode - see\n\u003ca href=\"#id34\"\u003e\u003cspan id=\"user-content-id35\"\u003e:ref:`page-creation-environments`\u003c/span\u003e\u003c/a\u003e).\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eTo customize the error page that's shown to the user, see the\n\u003ca href=\"#id36\"\u003e\u003cspan id=\"user-content-id37\"\u003e:doc:`/controller/error_pages`\u003c/span\u003e\u003c/a\u003e article.\u003c/p\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? That information is stored in Symfony's \u003ccode\u003eRequest\u003c/code\u003e\nobject. To access it in your controller, 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 index(Request $request, $firstName, $lastName)\n{\n $page = $request-\u0026gt;query-\u0026gt;get('page', 1);\n\n // ...\n}\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003e\u003ca href=\"#id38\"\u003e\u003cspan id=\"user-content-id39\"\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\u003cpre\u003e.. index::\n single: Controller; The session\n single: Session\n\n\u003c/pre\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 session service that you can use to store information\nabout the user between requests. Session is enabled by default, but will only be\nstarted if you read or write from it.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eSession storage and other configuration can be controlled under the\n\u003ca href=\"#id40\"\u003e\u003cspan id=\"user-content-id41\"\u003e:ref:`framework.session configuration \u0026lt;config-framework-session\u0026gt;`\u003c/span\u003e\u003c/a\u003e in\n\u003ccode\u003econfig/packages/framework.yaml\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eTo get the session, add an argument and type-hint it with\n\u003ca href=\"#id42\"\u003e\u003cspan id=\"user-content-id43\"\u003e:class:`Symfony\\\\Component\\\\HttpFoundation\\\\Session\\\\SessionInterface`\u003c/span\u003e\u003c/a\u003e:\u003c/p\u003e\n\u003cpre\u003euse Symfony\\Component\\HttpFoundation\\Session\\SessionInterface;\n\npublic function index(SessionInterface $session)\n{\n // stores an attribute for reuse during a later user request\n $session-\u0026gt;set('foo', 'bar');\n\n // gets the attribute set by another controller in another request\n $foobar = $session-\u0026gt;get('foobar');\n\n // uses a default value if the attribute doesn't exist\n $filters = $session-\u0026gt;get('filters', []);\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\u003cp dir=\"auto\"\u003eFor more info, see \u003ca href=\"#id44\"\u003e\u003cspan id=\"user-content-id45\"\u003e:doc:`/session`\u003c/span\u003e\u003c/a\u003e.\u003c/p\u003e\n\u003cpre\u003e.. index::\n single: Session; Flash messages\n\n\u003c/pre\u003e\n\u003ca name=\"user-content-id46\"\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=\"#id47\"\u003e\u003cspan id=\"user-content-id48\"\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 update(Request $request)\n{\n // ...\n\n if ($form-\u0026gt;isSubmitted() \u0026amp;\u0026amp; $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 using the \u003ccode\u003eflashes()\u003c/code\u003e method provided\nby the \u003ca href=\"#id49\"\u003e\u003cspan id=\"user-content-id50\"\u003e:ref:`Twig global app variable \u0026lt;twig-app-variable\u0026gt;`\u003c/span\u003e\u003c/a\u003e:\u003c/p\u003e\n\u003cpre lang=\"html+twig\"\u003e{# templates/base.html.twig #}\n\n{# read and display just one flash message type #}\n{% for message in app.flashes('notice') %}\n \u0026lt;div class=\"flash-notice\"\u0026gt;\n {{ message }}\n \u0026lt;/div\u0026gt;\n{% endfor %}\n\n{# read and display several types of flash messages #}\n{% for label, messages in app.flashes(['success', 'warning']) %}\n {% for message in messages %}\n \u0026lt;div class=\"flash-{{ label }}\"\u0026gt;\n {{ message }}\n \u0026lt;/div\u0026gt;\n {% endfor %}\n{% endfor %}\n\n{# read and display all flash messages #}\n{% for label, messages in app.flashes %}\n {% for message in messages %}\n \u0026lt;div class=\"flash-{{ label }}\"\u0026gt;\n {{ message }}\n \u0026lt;/div\u0026gt;\n {% endfor %}\n{% endfor %}\n\u003c/pre\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\u003cdiv dir=\"auto\"\u003e\n\u003cp dir=\"auto\"\u003eTip\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eYou can use the\n\u003ca href=\"#id51\"\u003e\u003cspan id=\"user-content-id52\"\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=\"#id53\"\u003e\u003cspan id=\"user-content-id54\"\u003e:ref:`earlier \u0026lt;controller-request-argument\u0026gt;`\u003c/span\u003e\u003c/a\u003e, Symfony 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 index(Request $request)\n{\n $request-\u0026gt;isXmlHttpRequest(); // is it an Ajax request?\n\n $request-\u0026gt;getPreferredLanguage(['en', 'fr']);\n\n // retrieves GET and POST variables respectively\n $request-\u0026gt;query-\u0026gt;get('page');\n $request-\u0026gt;request-\u0026gt;get('page');\n\n // retrieves 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 // retrieves a COOKIE value\n $request-\u0026gt;cookies-\u0026gt;get('PHPSESSID');\n\n // retrieves 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 a public \u003ccode\u003eheaders\u003c/code\u003e property.\nThis object is of the type \u003ca href=\"#id55\"\u003e\u003cspan id=\"user-content-id56\"\u003e:class:`Symfony\\\\Component\\\\HttpFoundation\\\\ResponseHeaderBag`\u003c/span\u003e\u003c/a\u003e\nand provides methods for getting and setting response headers. The header names are\nnormalized. As a result, the name \u003ccode\u003eContent-Type\u003c/code\u003e is equivalent to\nthe name \u003ccode\u003econtent-type\u003c/code\u003e or \u003ccode\u003econtent_type\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eIn Symfony, a controller is required to return a \u003ccode\u003eResponse\u003c/code\u003e object:\u003c/p\u003e\n\u003cpre\u003euse Symfony\\Component\\HttpFoundation\\Response;\n\n// creates a simple Response with a 200 status code (the default)\n$response = new Response('Hello '.$name, Response::HTTP_OK);\n\n// creates a CSS-response with a 200 status code\n$response = new Response('\u0026lt;style\u0026gt; ... \u0026lt;/style\u0026gt;');\n$response-\u0026gt;headers-\u0026gt;set('Content-Type', 'text/css');\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eTo facilitate this, different response objects are included to address different\nresponse types. Some of these are mentioned below. To learn more about the\n\u003ccode\u003eRequest\u003c/code\u003e and \u003ccode\u003eResponse\u003c/code\u003e (and different \u003ccode\u003eResponse\u003c/code\u003e classes), see the\n\u003ca href=\"#id57\"\u003e\u003cspan id=\"user-content-id58\"\u003e:ref:`HttpFoundation component documentation \u0026lt;component-http-foundation-request\u0026gt;`\u003c/span\u003e\u003c/a\u003e.\u003c/p\u003e\n\u003ca name=\"user-content-accessing-configuration-values\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eAccessing Configuration Values\u003c/h4\u003e\u003ca id=\"user-content-accessing-configuration-values\" class=\"anchor\" aria-label=\"Permalink: Accessing Configuration Values\" href=\"#accessing-configuration-values\"\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\"\u003eTo get the value of any \u003ca href=\"#id59\"\u003e\u003cspan id=\"user-content-id60\"\u003e:ref:`configuration parameter \u0026lt;configuration-parameters\u0026gt;`\u003c/span\u003e\u003c/a\u003e\nfrom a controller, use the \u003ccode\u003egetParameter()\u003c/code\u003e helper method:\u003c/p\u003e\n\u003cpre\u003e// ...\npublic function index()\n{\n $contentsDir = $this-\u0026gt;getParameter('kernel.project_dir').'/contents';\n // ...\n}\n\u003c/pre\u003e\n\u003ca name=\"user-content-returning-json-response\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eReturning JSON Response\u003c/h4\u003e\u003ca id=\"user-content-returning-json-response\" class=\"anchor\" aria-label=\"Permalink: Returning JSON Response\" href=\"#returning-json-response\"\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\"\u003eTo return JSON from a controller, use the \u003ccode\u003ejson()\u003c/code\u003e helper method. This returns a\n\u003ccode\u003eJsonResponse\u003c/code\u003e object that encodes the data automatically:\u003c/p\u003e\n\u003cpre\u003e// ...\npublic function index()\n{\n // returns '{\"username\":\"jane.doe\"}' and sets the proper Content-Type header\n return $this-\u0026gt;json(['username' =\u0026gt; 'jane.doe']);\n\n // the shortcut defines three optional arguments\n // return $this-\u0026gt;json($data, $status = 200, $headers = [], $context = []);\n}\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eIf the \u003ca href=\"#id61\"\u003e\u003cspan id=\"user-content-id62\"\u003e:doc:`serializer service \u0026lt;/serializer\u0026gt;`\u003c/span\u003e\u003c/a\u003e is enabled in your\napplication, it will be used to serialize the data to JSON. Otherwise,\nthe \u003ca href=\"#id63\"\u003e\u003cspan id=\"user-content-id64\"\u003e:phpfunction:`json_encode`\u003c/span\u003e\u003c/a\u003e function is used.\u003c/p\u003e\n\u003ca name=\"user-content-streaming-file-responses\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eStreaming File Responses\u003c/h4\u003e\u003ca id=\"user-content-streaming-file-responses\" class=\"anchor\" aria-label=\"Permalink: Streaming File Responses\" href=\"#streaming-file-responses\"\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 use the \u003ca href=\"#id65\"\u003e\u003cspan id=\"user-content-id66\"\u003e:method:`Symfony\\\\Bundle\\\\FrameworkBundle\\\\Controller\\\\AbstractController::file`\u003c/span\u003e\u003c/a\u003e\nhelper to serve a file from inside a controller:\u003c/p\u003e\n\u003cpre\u003epublic function download()\n{\n // send the file contents and force the browser to download it\n return $this-\u0026gt;file('/path/to/some_file.pdf');\n}\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eThe \u003ccode\u003efile()\u003c/code\u003e helper provides some arguments to configure its behavior:\u003c/p\u003e\n\u003cpre\u003euse Symfony\\Component\\HttpFoundation\\File\\File;\nuse Symfony\\Component\\HttpFoundation\\ResponseHeaderBag;\n\npublic function download()\n{\n // load the file from the filesystem\n $file = new File('/path/to/some_file.pdf');\n\n return $this-\u0026gt;file($file);\n\n // rename the downloaded file\n return $this-\u0026gt;file($file, 'custom_name.pdf');\n\n // display the file contents in the browser instead of downloading it\n return $this-\u0026gt;file('invoice_3241.pdf', 'my_invoice.pdf', ResponseHeaderBag::DISPOSITION_INLINE);\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\"\u003eIn Symfony, a controller is usually a class method which is used to accept\nrequests, and return a \u003ccode\u003eResponse\u003c/code\u003e object. When mapped with a URL, a controller\nbecomes accessible and its response can be viewed.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eTo facilitate the development of controllers, Symfony provides an\n\u003ccode\u003eAbstractController\u003c/code\u003e. It can be used to extend the controller class allowing\naccess to some frequently used utilities such as \u003ccode\u003erender()\u003c/code\u003e and\n\u003ccode\u003eredirectToRoute()\u003c/code\u003e. The \u003ccode\u003eAbstractController\u003c/code\u003e also provides the\n\u003ccode\u003ecreateNotFoundException()\u003c/code\u003e utility which is used to return a page not found\nresponse.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eIn other articles, 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=\"#id67\"\u003e\u003cspan id=\"user-content-id68\"\u003e:doc:`rendering templates with Twig \u0026lt;/templates\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 templates\n\n\u003c/pre\u003e\n\u003cpre\u003e.. toctree::\n :maxdepth: 1\n :glob:\n\n controller/*\n\n\u003c/pre\u003e\n\n\u003c/article\u003e","renderedFileInfo":null,"shortPath":null,"symbolsEnabled":true,"tabSize":8,"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":"NwekPMiiX7-c0LObUlYpbWbBGdd_JoVgZS6TPq6xDcLLst51nH5sKmbkmnB-c3Bsw530WkU3pYYl-xD3njl7Rw"},"/repos/preferences":{"post":"VY1WB4oxgGO70RnEeE79rue1TZAKV3V1rEHVayQBNPtphKDG10ROMZdhRSkc9yPkJbMsUAnx6fZiIAYFQ8bUNQ"}}},"title":"symfony-docs/controller.rst at 4.3 · 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