8000 symfony-docs/validation.rst at 4.2 · 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":"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":"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":"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":".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":"Dockerfile","path":"Dockerfile","contentType":"file"},{"name":"README.markdown","path":"README.markdown","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":"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":"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"},{"name":"web_link.rst","path":"web_link.rst","contentType":"file"},{"name":"workflow.rst","path":"workflow.rst","contentType":"file"}],"totalCount":76}},"fileTreeProcessingTime":53.893232,"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.2","listCacheKey":"v0:1751870253.0","canEdit":false,"refType":"branch","currentOid":"f82a650e14c272d2f4b9f382322458a357395a56"},"path":"validation.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":"validation.rst","displayUrl":"https://github.com/symfony/symfony-docs/blob/4.2/validation.rst?raw=true","headerInfo":{"blobSize":"22 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":"52d98fe","siteNavLoginPath":"/login?return_to=https%3A%2F%2Fgithub.com%2Fsymfony%2Fsymfony-docs%2Fblob%2F4.2%2Fvalidation.rst","isCSV":false,"isRichtext":true,"toc":[{"level":2,"text":"Validation","anchor":"validation","htmlText":"Validation"},{"level":3,"text":"Installation","anchor":"installation","htmlText":"Installation"},{"level":3,"text":"The Basics of Validation","anchor":"the-basics-of-validation","htmlText":"The Basics of Validation"},{"level":4,"text":"Using the validator Service","anchor":"using-the-validator-service","htmlText":"Using the validator Service"},{"level":3,"text":"Configuration","anchor":"configuration","htmlText":"Configuration"},{"level":3,"text":"Constraints","anchor":"constraints","htmlText":"Constraints"},{"level":4,"text":"Supported Constraints","anchor":"supported-constraints","htmlText":"Supported Constraints"},{"level":4,"text":"Constraint Configuration","anchor":"constraint-configuration","htmlText":"Constraint Configuration"},{"level":3,"text":"Constraints in Form Classes","anchor":"constraints-in-form-classes","htmlText":"Constraints in Form Classes"},{"level":3,"text":"Constraint Targets","anchor":"constraint-targets","htmlText":"Constraint Targets"},{"level":4,"text":"Properties","anchor":"properties","htmlText":"Properties"},{"level":4,"text":"Getters","anchor":"getters","htmlText":"Getters"},{"level":4,"text":"Classes","anchor":"classes","htmlText":"Classes"},{"level":3,"text":"Final Thoughts","anchor":"final-thoughts","htmlText":"Final Thoughts"},{"level":3,"text":"Learn more","anchor":"learn-more","htmlText":"Learn more"}],"lineInfo":{"truncatedLoc":"727","truncatedSloc":"542"},"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.2/validation.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.2/validation.rst","renderImageOrRaw":false,"richText":"\u003carticle class=\"markdown-body entry-content container-lg\" itemprop=\"text\"\u003e\u003cpre\u003e.. index::\n single: Validation\n\n\u003c/pre\u003e\n\u003ca name=\"user-content-validation\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eValidation\u003c/h2\u003e\u003ca id=\"user-content-validation\" class=\"anchor\" aria-label=\"Permalink: Validation\" href=\"#validation\"\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\"\u003eValidation is a very common task in web applications. Data entered in forms\nneeds to be validated. Data also needs to be validated before it is written\ninto a database or passed to a web service.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eSymfony provides a \u003ca href=\"https://github.com/symfony/validator\"\u003eValidator\u003c/a\u003e component that makes this task easy and\ntransparent. This component is based on the \u003ca href=\"http://jcp.org/en/jsr/detail?id=303\" rel=\"nofollow\"\u003eJSR303 Bean Validation specification\u003c/a\u003e.\u003c/p\u003e\n\u003ca name=\"user-content-installation\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eInstallation\u003c/h3\u003e\u003ca id=\"user-content-installation\" class=\"anchor\" aria-label=\"Permalink: Installation\" href=\"#installation\"\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 applications using \u003ca href=\"#id1\"\u003e\u003cspan id=\"user-content-id2\"\u003e:doc:`Symfony Flex \u0026lt;/setup/flex\u0026gt;`\u003c/span\u003e\u003c/a\u003e, run this command to\ninstall the validator before using it:\u003c/p\u003e\n\u003cpre lang=\"terminal\"\u003e$ composer require symfony/validator doctrine/annotations\n\u003c/pre\u003e\n\u003cpre\u003e.. index::\n single: Validation; The basics\n\n\u003c/pre\u003e\n\u003ca name=\"user-content-the-basics-of-validation\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eThe Basics of Validation\u003c/h3\u003e\u003ca id=\"user-content-the-basics-of-validation\" class=\"anchor\" aria-label=\"Permalink: The Basics of Validation\" href=\"#the-basics-of-validation\"\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 best way to understand validation is to see it in action. To start, suppose\nyou've created a plain-old-PHP object that you need to use somewhere in\nyour application:\u003c/p\u003e\n\u003cpre\u003e// src/Entity/Author.php\nnamespace App\\Entity;\n\nclass Author\n{\n public $name;\n}\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eSo far, this is just an ordinary class that serves some purpose inside your\napplication. The goal of validation is to tell you if the data\nof an object is valid. For this to work, you'll configure a list of rules\n(called \u003ca href=\"#id3\"\u003e\u003cspan id=\"user-content-id4\"\u003e:ref:`constraints \u0026lt;validation-constraints\u0026gt;`\u003c/span\u003e\u003c/a\u003e) that the object must\nfollow in order to be valid. These rules are usually defined using PHP code or\nannotations but they can also be defined as a \u003ccode\u003evalidation.yaml\u003c/code\u003e or\n\u003ccode\u003evalidation.xml\u003c/code\u003e file inside the \u003ccode\u003econfig/validator/\u003c/code\u003e directory:\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eFor example, to guarantee that the \u003ccode\u003e$name\u003c/code\u003e property is not empty, add the\nfollowing:\u003c/p\u003e\n\u003cpre\u003e.. configuration-block::\n\n .. code-block:: php-annotations\n\n // src/Entity/Author.php\n\n // ...\n use Symfony\\Component\\Validator\\Constraints as Assert;\n\n class Author\n {\n /**\n * @Assert\\NotBlank\n */\n public $name;\n }\n\n .. code-block:: yaml\n\n # config/validator/validation.yaml\n App\\Entity\\Author:\n properties:\n name:\n - NotBlank: ~\n\n .. code-block:: xml\n\n \u0026lt;!-- config/validator/validation.xml --\u0026gt;\n \u0026lt;?xml version=\"1.0\" encoding=\"UTF-8\" ?\u0026gt;\n \u0026lt;constraint-mapping xmlns=\"http://symfony.com/schema/dic/constraint-mapping\"\n xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n xsi:schemaLocation=\"http://symfony.com/schema/dic/constraint-mapping\n https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd\"\u0026gt;\n\n \u0026lt;class name=\"App\\Entity\\Author\"\u0026gt;\n \u0026lt;property name=\"name\"\u0026gt;\n \u0026lt;constraint name=\"NotBlank\"/\u0026gt;\n \u0026lt;/property\u0026gt;\n \u0026lt;/class\u0026gt;\n \u0026lt;/constraint-mapping\u0026gt;\n\n .. code-block:: php\n\n // src/Entity/Author.php\n\n // ...\n use Symfony\\Component\\Validator\\Constraints\\NotBlank;\n use Symfony\\Component\\Validator\\Mapping\\ClassMetadata;\n\n class Author\n {\n public $name;\n\n public static function loadValidatorMetadata(ClassMetadata $metadata)\n {\n $metadata-\u0026gt;addPropertyConstraint('name', new NotBlank());\n }\n }\n\n\u003c/pre\u003e\n\u003cdiv dir=\"auto\"\u003e\n\u003cp dir=\"auto\"\u003eTip\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eProtected and private properties can also be validated, as well as \"getter\"\nmethods (see \u003ca href=\"#id5\"\u003e\u003cspan id=\"user-content-id6\"\u003e:ref:`validator-constraint-targets`\u003c/span\u003e\u003c/a\u003e).\u003c/p\u003e\n\u003c/div\u003e\n\u003cpre\u003e.. index::\n single: Validation; Using the validator\n\n\u003c/pre\u003e\n\u003ca name=\"user-content-using-the-validator-service\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eUsing the \u003ccode\u003evalidator\u003c/code\u003e Service\u003c/h4\u003e\u003ca id=\"user-content-using-the-validator-service\" class=\"anchor\" aria-label=\"Permalink: Using the validator Service\" href=\"#using-the-validator-service\"\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, to actually validate an \u003ccode\u003eAuthor\u003c/code\u003e object, use the \u003ccode\u003evalidate()\u003c/code\u003e method\non the \u003ccode\u003evalidator\u003c/code\u003e service (class \u003ca href=\"#id7\"\u003e\u003cspan id=\"user-content-id8\"\u003e:class:`Symfony\\\\Component\\\\Validator\\\\Validator`\u003c/span\u003e\u003c/a\u003e).\nThe job of the \u003ccode\u003evalidator\u003c/code\u003e is to read the constraints (i.e. rules)\nof a class and verify if the data on the object satisfies those\nconstraints. If validation fails, a non-empty list of errors\n(class \u003ca href=\"#id9\"\u003e\u003cspan id=\"user-content-id10\"\u003e:class:`Symfony\\\\Component\\\\Validator\\\\ConstraintViolationList`\u003c/span\u003e\u003c/a\u003e) is\nreturned. Take this simple example from inside a controller:\u003c/p\u003e\n\u003cpre\u003e// ...\nuse App\\Entity\\Author;\nuse Symfony\\Component\\HttpFoundation\\Response;\nuse Symfony\\Component\\Validator\\Validator\\ValidatorInterface;\n\n// ...\npublic function author(ValidatorInterface $validator)\n{\n $author = new Author();\n\n // ... do something to the $author object\n\n $errors = $validator-\u0026gt;validate($author);\n\n if (count($errors) \u0026gt; 0) {\n /*\n * Uses a __toString method on the $errors variable which is a\n * ConstraintViolationList object. This gives us a nice string\n * for debugging.\n */\n $errorsString = (string) $errors;\n\n return new Response($errorsString);\n }\n\n return new Response('The author is valid! Yes!');\n}\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eIf the \u003ccode\u003e$name\u003c/code\u003e property is empty, you will see the following error\nmessage:\u003c/p\u003e\n\u003cpre lang=\"text\"\u003eObject(App\\Entity\\Author).name:\n This value should not be blank\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eIf you insert a value into the \u003ccode\u003ename\u003c/code\u003e property, the happy success message\nwill appear.\u003c/p\u003e\n\u003cdiv dir=\"auto\"\u003e\n\u003cp dir=\"auto\"\u003eTip\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eMost of the time, you won't interact directly with the \u003ccode\u003evalidator\u003c/code\u003e\nservice or need to worry about printing out the errors. Most of the time,\nyou'll use validation indirectly when handling submitted form data. For\nmore information, see the \u003ca href=\"#id11\"\u003e\u003cspan id=\"user-content-id12\"\u003e:ref:`forms-form-validation`\u003c/span\u003e\u003c/a\u003e.\u003c/p\u003e\n\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eYou could also pass the collection of errors into a template:\u003c/p\u003e\n\u003cpre\u003eif (count($errors) \u0026gt; 0) {\n return $this-\u0026gt;render('author/validation.html.twig', [\n 'errors' =\u0026gt; $errors,\n ]);\n}\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eInside the template, you can output the list of errors exactly as needed:\u003c/p\u003e\n\u003cpre lang=\"html+twig\"\u003e{# templates/author/validation.html.twig #}\n\u0026lt;h3\u0026gt;The author has the following errors\u0026lt;/h3\u0026gt;\n\u0026lt;ul\u0026gt;\n{% for error in errors %}\n \u0026lt;li\u0026gt;{{ error.message }}\u0026lt;/li\u0026gt;\n{% endfor %}\n\u0026lt;/ul\u0026gt;\n\u003c/pre\u003e\n\u003cdiv dir=\"auto\"\u003e\n\u003cp dir=\"auto\"\u003eNote\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eEach validation error (called a \"constraint violation\"), is represented by\na \u003ca href=\"#id13\"\u003e\u003cspan id=\"user-content-id14\"\u003e:class:`Symfony\\\\Component\\\\Validator\\\\ConstraintViolation`\u003c/span\u003e\u003c/a\u003e object.\u003c/p\u003e\n\u003c/div\u003e\n\u003cpre\u003e.. index::\n pair: Validation; Configuration\n\n\u003c/pre\u003e\n\u003ca name=\"user-content-configuration\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eConfiguration\u003c/h3\u003e\u003ca id=\"user-content-configuration\" class=\"anchor\" aria-label=\"Permalink: Configuration\" href=\"#configuration\"\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\"\u003eBefore using the Symfony validator, make sure it's enabled in the main config\nfile:\u003c/p\u003e\n\u003cpre\u003e.. configuration-block::\n\n .. code-block:: yaml\n\n # config/packages/framework.yaml\n framework:\n validation: { enabled: true }\n\n .. code-block:: xml\n\n \u0026lt;!-- config/packages/framework.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 xmlns:framework=\"http://symfony.com/schema/dic/symfony\"\n xsi:schemaLocation=\"http://symfony.com/schema/dic/services\n https://symfony.com/schema/dic/services/services-1.0.xsd\n http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd\"\u0026gt;\n\n \u0026lt;framework:config\u0026gt;\n \u0026lt;framework:validation enabled=\"true\"/\u0026gt;\n \u0026lt;/framework:config\u0026gt;\n \u0026lt;/container\u0026gt;\n\n .. code-block:: php\n\n // config/packages/framework.php\n $container-\u0026gt;loadFromExtension('framework', [\n 'validation' =\u0026gt; [\n 'enabled' =\u0026gt; true,\n ],\n ]);\n\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eBesides, if you plan to use annotations to configure validation, replace the\nprevious configuration by the following:\u003c/p\u003e\n\u003cpre\u003e.. configuration-block::\n\n .. code-block:: yaml\n\n # config/packages/framework.yaml\n framework:\n validation: { enable_annotations: true }\n\n .. code-block:: xml\n\n \u0026lt;!-- config/packages/framework.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 xmlns:framework=\"http://symfony.com/schema/dic/symfony\"\n xsi:schemaLocation=\"http://symfony.com/schema/dic/services\n https://symfony.com/schema/dic/services/services-1.0.xsd\n http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd\"\u0026gt;\n\n \u0026lt;framework:config\u0026gt;\n \u0026lt;framework:validation enable-annotations=\"true\"/\u0026gt;\n \u0026lt;/framework:config\u0026gt;\n \u0026lt;/container\u0026gt;\n\n .. code-block:: php\n\n // config/packages/framework.php\n $container-\u0026gt;loadFromExtension('framework', [\n 'validation' =\u0026gt; [\n 'enable_annotations' =\u0026gt; true,\n ],\n ]);\n\n\u003c/pre\u003e\n\u003cpre\u003e.. index::\n single: Validation; Constraints\n\n\u003c/pre\u003e\n\u003ca name=\"user-content-constraints\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eConstraints\u003c/h3\u003e\u003ca id=\"user-content-constraints\" class=\"anchor\" aria-label=\"Permalink: Constraints\" href=\"#constraints\"\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 \u003ccode\u003evalidator\u003c/code\u003e is designed to validate objects against \u003cem\u003econstraints\u003c/em\u003e (i.e.\nrules). In order to validate an object, simply map one or more constraints\nto its class and then pass it to the \u003ccode\u003evalidator\u003c/code\u003e service.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eBehind the scenes, a constraint is simply a PHP object that makes an assertive\nstatement. In real life, a constraint could be: 'The cake must not be burned'.\nIn Symfony, constraints are similar: they are assertions that a condition\nis true. Given a value, a constraint will tell you if that value\nadheres to the rules of the constraint.\u003c/p\u003e\n\u003ca name=\"user-content-supported-constraints\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eSupported Constraints\u003c/h4\u003e\u003ca id=\"user-content-supported-constraints\" class=\"anchor\" aria-label=\"Permalink: Supported Constraints\" href=\"#supported-constraints\"\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 packages many of the most commonly-needed constraints:\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eYou can also create your own custom constraints. This topic is covered in\nthe \u003ca href=\"#id15\"\u003e\u003cspan id=\"user-content-id16\"\u003e:doc:`/validation/custom_constraint`\u003c/span\u003e\u003c/a\u003e article.\u003c/p\u003e\n\u003cpre\u003e.. index::\n single: Validation; Constraints configuration\n\n\u003c/pre\u003e\n\u003ca name=\"user-content-constraint-configuration\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eConstraint Configuration\u003c/h4\u003e\u003ca id=\"user-content-constraint-configuration\" class=\"anchor\" aria-label=\"Permalink: Constraint Configuration\" href=\"#constraint-configuration\"\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\"\u003eSome constraints, like \u003ca href=\"#id17\"\u003e\u003cspan id=\"user-content-id18\"\u003e:doc:`NotBlank \u0026lt;/reference/constraints/NotBlank\u0026gt;`\u003c/span\u003e\u003c/a\u003e,\nare simple whereas others, like the \u003ca href=\"#id19\"\u003e\u003cspan id=\"user-content-id20\"\u003e:doc:`Choice \u0026lt;/reference/constraints/Choice\u0026gt;`\u003c/span\u003e\u003c/a\u003e\nconstraint, have several configuration options available. Suppose that the\n\u003ccode\u003eAuthor\u003c/code\u003e class has another property called \u003ccode\u003egenre\u003c/code\u003e that defines the\nliterature genre mostly associated with the author, which can be set to either\n\"fiction\" or \"non-fiction\":\u003c/p\u003e\n\u003cpre\u003e.. configuration-block::\n\n .. code-block:: php-annotations\n\n // src/Entity/Author.php\n\n // ...\n use Symfony\\Component\\Validator\\Constraints as Assert;\n\n class Author\n {\n /**\n * @Assert\\Choice(\n * choices = { \"fiction\", \"non-fiction\" },\n * message = \"Choose a valid genre.\"\n * )\n */\n public $genre;\n\n // ...\n }\n\n .. code-block:: yaml\n\n # config/validator/validation.yaml\n App\\Entity\\Author:\n properties:\n genre:\n - Choice: { choices: [fiction, non-fiction], message: Choose a valid genre. }\n # ...\n\n .. code-block:: xml\n\n \u0026lt;!-- config/validator/validation.xml --\u0026gt;\n \u0026lt;?xml version=\"1.0\" encoding=\"UTF-8\" ?\u0026gt;\n \u0026lt;constraint-mapping xmlns=\"http://symfony.com/schema/dic/constraint-mapping\"\n xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n xsi:schemaLocation=\"http://symfony.com/schema/dic/constraint-mapping\n https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd\"\u0026gt;\n\n \u0026lt;class name=\"App\\Entity\\Author\"\u0026gt;\n \u0026lt;property name=\"genre\"\u0026gt;\n \u0026lt;constraint name=\"Choice\"\u0026gt;\n \u0026lt;option name=\"choices\"\u0026gt;\n \u0026lt;value\u0026gt;fiction\u0026lt;/value\u0026gt;\n \u0026lt;value\u0026gt;non-fiction\u0026lt;/value\u0026gt;\n \u0026lt;/option\u0026gt;\n \u0026lt;option name=\"message\"\u0026gt;Choose a valid genre.\u0026lt;/option\u0026gt;\n \u0026lt;/constraint\u0026gt;\n \u0026lt;/property\u0026gt;\n\n \u0026lt;!-- ... --\u0026gt;\n \u0026lt;/class\u0026gt;\n \u0026lt;/constraint-mapping\u0026gt;\n\n .. code-block:: php\n\n // src/Entity/Author.php\n\n // ...\n use Symfony\\Component\\Validator\\Constraints as Assert;\n use Symfony\\Component\\Validator\\Mapping\\ClassMetadata;\n\n class Author\n {\n public $genre;\n\n // ...\n\n public static function loadValidatorMetadata(ClassMetadata $metadata)\n {\n // ...\n\n $metadata-\u0026gt;addPropertyConstraint('genre', new Assert\\Choice([\n 'choices' =\u0026gt; ['fiction', 'non-fiction'],\n 'message' =\u0026gt; 'Choose a valid genre.',\n ]));\n }\n }\n\n\u003c/pre\u003e\n\u003cp id=\"user-content-validation-default-option\" dir=\"auto\"\u003eThe options of a constraint can always be passed in as an array. Some constraints,\nhowever, also allow you to pass the value of one, \"\u003cem\u003edefault\u003c/em\u003e\", option in place\nof the array. In the case of the \u003ccode\u003eChoice\u003c/code\u003e constraint, the \u003ccode\u003echoices\u003c/code\u003e\noptions can be specified in this way.\u003c/p\u003e\n\u003cpre\u003e.. configuration-block::\n\n .. code-block:: php-annotations\n\n // src/Entity/Author.php\n\n // ...\n use Symfony\\Component\\Validator\\Constraints as Assert;\n\n class Author\n {\n /**\n * @Assert\\Choice({\"fiction\", \"non-fiction\"})\n */\n protected $genre;\n\n // ...\n }\n\n .. code-block:: yaml\n\n # config/validator/validation.yaml\n App\\Entity\\Author:\n properties:\n genre:\n - Choice: [fiction, non-fiction]\n # ...\n\n .. code-block:: xml\n\n \u0026lt;!-- config/validator/validation.xml --\u0026gt;\n \u0026lt;?xml version=\"1.0\" encoding=\"UTF-8\" ?\u0026gt;\n \u0026lt;constraint-mapping xmlns=\"http://symfony.com/schema/dic/constraint-mapping\"\n xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n xsi:schemaLocation=\"http://symfony.com/schema/dic/constraint-mapping\n https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd\"\u0026gt;\n\n \u0026lt;class name=\"App\\Entity\\Author\"\u0026gt;\n \u0026lt;property name=\"genre\"\u0026gt;\n \u0026lt;constraint name=\"Choice\"\u0026gt;\n \u0026lt;value\u0026gt;fiction\u0026lt;/value\u0026gt;\n \u0026lt;value\u0026gt;non-fiction\u0026lt;/value\u0026gt;\n \u0026lt;/constraint\u0026gt;\n \u0026lt;/property\u0026gt;\n\n \u0026lt;!-- ... --\u0026gt;\n \u0026lt;/class\u0026gt;\n \u0026lt;/constraint-mapping\u0026gt;\n\n .. code-block:: php\n\n // src/Entity/Author.php\n\n // ...\n use Symfony\\Component\\Validator\\Constraints as Assert;\n use Symfony\\Component\\Validator\\Mapping\\ClassMetadata;\n\n class Author\n {\n protected $genre;\n\n public static function loadValidatorMetadata(ClassMetadata $metadata)\n {\n // ...\n\n $metadata-\u0026gt;addPropertyConstraint(\n 'genre',\n new Assert\\Choice(['fiction', 'non-fiction'])\n );\n }\n }\n\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eThis is purely meant to make the configuration of the most common option of\na constraint shorter and quicker.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eIf you're ever unsure of how to specify an option, either check \u003ca href=\"#id21\"\u003e\u003cspan id=\"user-content-id22\"\u003e:namespace:`Symfony\\\\Component\\\\Validator\\\\Constraints`\u003c/span\u003e\u003c/a\u003e\nfor the constraint or play it safe by always passing in an array of options\n(the first method shown above).\u003c/p\u003e\n\u003ca name=\"user-content-constraints-in-form-classes\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eConstraints in Form Classes\u003c/h3\u003e\u003ca id=\"user-content-constraints-in-form-classes\" class=\"anchor\" aria-label=\"Permalink: Constraints in Form Classes\" href=\"#constraints-in-form-classes\"\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\"\u003eConstraints can be defined while building the form via the \u003ccode\u003econstraints\u003c/code\u003e option\nof the form fields:\u003c/p\u003e\n\u003cpre\u003epublic function buildForm(FormBuilderInterface $builder, array $options)\n{\n $builder\n -\u0026gt;add('myField', TextType::class, [\n 'required' =\u0026gt; true,\n 'constraints' =\u0026gt; [new Length(['min' =\u0026gt; 3])]\n ])\n ;\n}\n\u003c/pre\u003e\n\u003cpre\u003e.. index::\n single: Validation; Constraint targets\n\n\u003c/pre\u003e\n\u003ca name=\"user-content-constraint-targets\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eConstraint Targets\u003c/h3\u003e\u003ca id=\"user-content-constraint-targets\" class=\"anchor\" aria-label=\"Permalink: Constraint Targets\" href=\"#constraint-targets\"\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\"\u003eConstraints can be applied to a class property (e.g. \u003ccode\u003ename\u003c/code\u003e), a public\ngetter method (e.g. \u003ccode\u003egetFullName()\u003c/code\u003e) or an entire class. Property constraints\nare the most common and easy to use. Getter constraints allow you to specify\nmore complex validation rules. Finally, class constraints are intended\nfor scenarios where you want to validate a class as a whole.\u003c/p\u003e\n\u003cpre\u003e.. index::\n single: Validation; Property constraints\n\n\u003c/pre\u003e\n\u003ca name=\"user-content-properties\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eProperties\u003c/h4\u003e\u003ca id=\"user-content-properties\" class=\"anchor\" aria-label=\"Permalink: Properties\" href=\"#properties\"\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\"\u003eValidating class properties is the most basic validation technique. Symfony\nallows you to validate private, protected or public properties. The next\nlisting shows you how to configure the \u003ccode\u003e$firstName\u003c/code\u003e property of an \u003ccode\u003eAuthor\u003c/code\u003e\nclass to have at least 3 characters.\u003c/p\u003e\n\u003cpre\u003e.. configuration-block::\n\n .. code-block:: php-annotations\n\n // src/Entity/Author.php\n\n // ...\n use Symfony\\Component\\Validator\\Constraints as Assert;\n\n class Author\n {\n /**\n * @Assert\\NotBlank\n * @Assert\\Length(min=3)\n */\n private $firstName;\n }\n\n .. code-block:: yaml\n\n # config/validator/validation.yaml\n App\\Entity\\Author:\n properties:\n firstName:\n - NotBlank: ~\n - Length:\n min: 3\n\n .. code-block:: xml\n\n \u0026lt;!-- config/validator/validation.xml --\u0026gt;\n \u0026lt;?xml version=\"1.0\" encoding=\"UTF-8\" ?\u0026gt;\n \u0026lt;constraint-mapping xmlns=\"http://symfony.com/schema/dic/constraint-mapping\"\n xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n xsi:schemaLocation=\"http://symfony.com/schema/dic/constraint-mapping\n https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd\"\u0026gt;\n\n \u0026lt;class name=\"App\\Entity\\Author\"\u0026gt;\n \u0026lt;property name=\"firstName\"\u0026gt;\n \u0026lt;constraint name=\"NotBlank\"/\u0026gt;\n \u0026lt;constraint name=\"Length\"\u0026gt;\n \u0026lt;option name=\"min\"\u0026gt;3\u0026lt;/option\u0026gt;\n \u0026lt;/constraint\u0026gt;\n \u0026lt;/property\u0026gt;\n \u0026lt;/class\u0026gt;\n \u0026lt;/constraint-mapping\u0026gt;\n\n .. code-block:: php\n\n // src/Entity/Author.php\n\n // ...\n use Symfony\\Component\\Validator\\Constraints as Assert;\n use Symfony\\Component\\Validator\\Mapping\\ClassMetadata;\n\n class Author\n {\n private $firstName;\n\n public static function loadValidatorMetadata(ClassMetadata $metadata)\n {\n $metadata-\u0026gt;addPropertyConstraint('firstName', new Assert\\NotBlank());\n $metadata-\u0026gt;addPropertyConstraint(\n 'firstName',\n new Assert\\Length([\"min\" =\u0026gt; 3])\n );\n }\n }\n\n\u003c/pre\u003e\n\u003cpre\u003e.. index::\n single: Validation; Getter constraints\n\n\u003c/pre\u003e\n\u003ca name=\"user-content-getters\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eGetters\u003c/h4\u003e\u003ca id=\"user-content-getters\" class=\"anchor\" aria-label=\"Permalink: Getters\" href=\"#getters\"\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\"\u003eConstraints can also be applied to the return value of a method. Symfony\nallows you to add a constraint to any public method whose name starts with\n\"get\", \"is\" or \"has\". In this guide, these types of methods are referred to\nas \"getters\".\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe benefit of this technique is that it allows you to validate your object\ndynamically. For example, suppose you want to make sure that a password field\ndoesn't match the first name of the user (for security reasons). You can\ndo this by creating an \u003ccode\u003eisPasswordSafe()\u003c/code\u003e method, and then asserting that\nthis method must return \u003ccode\u003etrue\u003c/code\u003e:\u003c/p\u003e\n\u003cpre\u003e.. configuration-block::\n\n .. code-block:: php-annotations\n\n // src/Entity/Author.php\n\n // ...\n use Symfony\\Component\\Validator\\Constraints as Assert;\n\n class Author\n {\n /**\n * @Assert\\IsTrue(message=\"The password cannot match your first name\")\n */\n public function isPasswordSafe()\n {\n // ... return true or false\n }\n }\n\n .. code-block:: yaml\n\n # config/validator/validation.yaml\n App\\Entity\\Author:\n getters:\n passwordSafe:\n - 'IsTrue': { message: 'The password cannot match your first name' }\n\n .. code-block:: xml\n\n \u0026lt;!-- config/validator/validation.xml --\u0026gt;\n \u0026lt;?xml version=\"1.0\" encoding=\"UTF-8\" ?\u0026gt;\n \u0026lt;constraint-mapping xmlns=\"http://symfony.com/schema/dic/constraint-mapping\"\n xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n xsi:schemaLocation=\"http://symfony.com/schema/dic/constraint-mapping\n https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd\"\u0026gt;\n\n \u0026lt;class name=\"App\\Entity\\Author\"\u0026gt;\n \u0026lt;getter property=\"passwordSafe\"\u0026gt;\n \u0026lt;constraint name=\"IsTrue\"\u0026gt;\n \u0026lt;option name=\"message\"\u0026gt;The password cannot match your first name\u0026lt;/option\u0026gt;\n \u0026lt;/constraint\u0026gt;\n \u0026lt;/getter\u0026gt;\n \u0026lt;/class\u0026gt;\n \u0026lt;/constraint-mapping\u0026gt;\n\n .. code-block:: php\n\n // src/Entity/Author.php\n\n // ...\n use Symfony\\Component\\Validator\\Constraints as Assert;\n use Symfony\\Component\\Validator\\Mapping\\ClassMetadata;\n\n class Author\n {\n public static function loadValidatorMetadata(ClassMetadata $metadata)\n {\n $metadata-\u0026gt;addGetterConstraint('passwordSafe', new Assert\\IsTrue([\n 'message' =\u0026gt; 'The password cannot match your first name',\n ]));\n }\n }\n\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eNow, create the \u003ccode\u003eisPasswordSafe()\u003c/code\u003e method and include the logic you need:\u003c/p\u003e\n\u003cpre\u003epublic function isPasswordSafe()\n{\n return $this-\u0026gt;firstName !== $this-\u0026gt;password;\n}\n\u003c/pre\u003e\n\u003cdiv dir=\"auto\"\u003e\n\u003cp dir=\"auto\"\u003eNote\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe keen-eyed among you will have noticed that the prefix of the getter\n(\"get\", \"is\" or \"has\") is omitted in the mappings for the YAML, XML and PHP\nformats. This allows you to move the constraint to a property with the same\nname later (or vice versa) without changing your validation logic.\u003c/p\u003e\n\u003c/div\u003e\n\u003ca name=\"user-content-classes\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eClasses\u003c/h4\u003e\u003ca id=\"user-content-classes\" class=\"anchor\" aria-label=\"Permalink: Classes\" href=\"#classes\"\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\"\u003eSome constraints apply to the entire class being validated. For example,\nthe \u003ca href=\"#id23\"\u003e\u003cspan id=\"user-content-id24\"\u003e:doc:`Callback \u0026lt;/reference/constraints/Callback\u0026gt;`\u003c/span\u003e\u003c/a\u003e constraint is a generic\nconstraint that's applied to the class itself. When that class is validated,\nmethods specified by that constraint are simply executed so that each can\nprovide more custom validation.\u003c/p\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\"\u003eThe Symfony \u003ccode\u003evalidator\u003c/code\u003e is a powerful tool that can be leveraged to\nguarantee that the data of any object is \"valid\". The power behind validation\nlies in \"constraints\", which are rules that you can apply to properties or\ngetter methods of your object. And while you'll most commonly use the validation\nframework indirectly when using forms, remember that it can be used anywhere\nto validate any object.\u003c/p\u003e\n\u003ca name=\"user-content-learn-more\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eLearn more\u003c/h3\u003e\u003ca id=\"user-content-learn-more\" class=\"anchor\" aria-label=\"Permalink: Learn more\" href=\"#learn-more\"\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 :maxdepth: 1\n :glob:\n\n /validation/*\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":"RrfkFNjGRShyy1-HblXtzefKHMWwGU7b2k3YFNefSZo0hvx_PixV88z7VSnN6I9IatUJL6-t-3rnxwcLKrGWNA"},"/repos/preferences":{"post":"BttLf5LuMI61AkjYL6Z6PpqsoZFUVd0DVYmU0tYSeudQ_V8FZAJJzPg16AJKhCq5vH_r8vRxEJd-KHtGFyCrug"}}},"title":"symfony-docs/validation.rst at 4.2 · 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