{"id":853,"date":"2025-05-05T10:28:17","date_gmt":"2025-05-05T10:28:17","guid":{"rendered":"https:\/\/www.cmarix.com\/qanda\/?p=853"},"modified":"2026-02-05T12:06:35","modified_gmt":"2026-02-05T12:06:35","slug":"laravel-performance-optimization-tips-beyond-queries","status":"publish","type":"post","link":"https:\/\/www.cmarix.com\/qanda\/laravel-performance-optimization-tips-beyond-queries\/","title":{"rendered":"How to Create Custom Validation Rules and Messages of Business Logic in Laravel?"},"content":{"rendered":"\n<p>Built-in validation rules such as required, email, or max are not enough for most real-word applications. Your requirements might need custom business logic such as checking if a username contains a certain word, or if a user has a specific role.<\/p>\n\n\n\n<p>Laravel gives you three main ways to define custom validation:<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Closure-Based Custom Rules (Inline in Controller)<\/h2>\n\n\n\n<p>This is the simplest way to define a custom rule using a closure (anonymous function) directly in your validation array.<\/p>\n\n\n\n<p>Example: Disallow usernames containing \u201cadmin\u201d<br><strong>PHP:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$request-&gt;validate(&#91;\n    'username' =&gt; &#91;\n        'required',\n        function ($attribute, $value, $fail) {\n            if (stripos($value, 'admin') !== false) {\n                $fail('The username cannot contain the word \"admin\".');\n            }\n        },\n    ],\n]);<\/code><\/pre>\n\n\n\n<p>When to use: Small, one-time rules specific to a form.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Custom Rule Class (Reusable Rules)<\/h2>\n\n\n\n<p>Use Laravel\u2019s artisan command to create a custom rule class.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 1: Create the rule<\/h3>\n\n\n\n<p>Bash:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>php artisan make:rule Uppercase<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Step 2: Define logic in the rule class<\/h3>\n\n\n\n<p>PHP:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ app\/Rules\/Uppercase.php\nnamespace App\\Rules;\nuse Illuminate\\Contracts\\Validation\\Rule;\nclass Uppercase implements Rule\n{\n    public function passes($attribute, $value)\n    {\n        return strtoupper($value) === $value;\n    }\n    public function message()\n    {\n        return 'The :attribute must be in uppercase.';\n    }\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Step 3: Use the rule in a controller<\/h3>\n\n\n\n<p><strong>PHP:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>use App\\Rules\\Uppercase;\n$request-&gt;validate(&#91;\n    'title' =&gt; &#91;'required', new Uppercase],\n]);<\/code><\/pre>\n\n\n\n<p>When to use: When the rule will be reused across different forms or logic is too complex for closures.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Extending the Validator (Custom Rule Name)<\/h2>\n\n\n\n<p>You can register your own validation rule globally using Laravel\u2019s <em>Validator::extend<\/em> method (typically in a service provider).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 1: Extend Validator<\/h3>\n\n\n\n<p><strong>PHP<\/strong>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>use Illuminate\\Support\\Facades\\Validator;\npublic function boot()\n{\n    Validator::extend('foo', function ($attribute, $value, $parameters, $validator) {\n        return $value === 'foo';\n    });\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Step 2: Use the new rule name<\/h3>\n\n\n\n<p><strong>PHP<\/strong>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$request-&gt;validate(&#91;\n    'code' =&gt; 'required|foo',\n]);<\/code><\/pre>\n\n\n\n<p><strong>Optional: Custom message<\/strong><\/p>\n\n\n\n<p>PHP:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ resources\/lang\/en\/validation.php\n'foo' =&gt; 'The :attribute must be \"foo\".',<\/code><\/pre>\n\n\n\n<p><strong>When to use<\/strong>: When you want clean, named rules you can apply like built-in rules.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Customizing Error Messages (All Methods)<\/h2>\n\n\n\n<p>You can customize error messages like this:<\/p>\n\n\n\n<p>PHP:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$request-&gt;validate(&#91;\n    'username' =&gt; 'required|min:5',\n], &#91;\n    'username.required' =&gt; 'Please enter your username.',\n    'username.min' =&gt; 'Your username must be at least :min characters long.',\n]);<\/code><\/pre>\n\n\n\n<p>This helps you keep messages user-friendly and in plain language.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Example Use Case: Validating Age Must Be Over 18<\/h3>\n\n\n\n<p><strong>Custom Rule Class<\/strong><\/p>\n\n\n\n<p><strong>Bash:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>php artisan make:rule AgeOver18<\/code><\/pre>\n\n\n\n<p><strong>Rule Logic<\/strong><\/p>\n\n\n\n<p>PHP:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public function passes($attribute, $value)\n{\n    return Carbon\\Carbon::parse($value)-&gt;age &gt;= 18;\n}\npublic function message()\n{\n    return 'You must be at least 18 years old.';\n}<\/code><\/pre>\n\n\n\n<p><strong>Usage<\/strong><\/p>\n\n\n\n<p>PHP:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$request-&gt;validate(&#91;\n    'dob' =&gt; &#91;'required', 'date', new AgeOver18],\n]);<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Summary Table<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><strong>Method<\/strong><\/td><td><strong>Use When<\/strong><\/td><td><strong>Reusability<\/strong><\/td><td><strong>Complexity<\/strong><\/td><\/tr><tr><td><strong>Closure-based<\/strong><\/td><td>Quick one-off logic<\/td><td>No<\/td><td>Simple<\/td><\/tr><tr><td><strong>Custom Rule Class<\/strong><\/td><td>Rule used in multiple places<\/td><td>Yes<\/td><td>Medium<\/td><\/tr><tr><td><strong>Validator Extension<\/strong><\/td><td>Want named rules<\/td><td>Yes<\/td><td>Advanced<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Pro Tips<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Group multiple custom rules in one file for better organization.<\/li>\n\n\n\n<li>Reuse custom rule classes to follow DRY principles.<\/li>\n\n\n\n<li>Store messages in <em>resources\/lang<\/em> for localization support.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Built-in validation rules such as required, email, or max are not enough for most real-word applications. Your requirements might need custom business logic such as checking if a username contains a certain word, or if a user has a specific role. Laravel gives you three main ways to define custom validation: Closure-Based Custom Rules (Inline [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":1019,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[13,3],"tags":[],"class_list":["post-853","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-laravel","category-web"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/posts\/853","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/comments?post=853"}],"version-history":[{"count":11,"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/posts\/853\/revisions"}],"predecessor-version":[{"id":918,"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/posts\/853\/revisions\/918"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/media\/1019"}],"wp:attachment":[{"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/media?parent=853"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/categories?post=853"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/tags?post=853"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}