8

Is there any specific rule for domain name? Was googling for about an hour, but didn't get the list of rules. I've tried "domain" => "required|url" but it's requering a protocol type in it, so it's not the best option for me.

CrazyWu
  • 577
  • 1
  • 6
  • 15
  • There's a rule for URLs (see [docs](https://laravel.com/docs/5.5/validation#available-validation-rules)), but you'll probably have to write your own _regular expression_ for it (a custom rule). If you want that, you'll have to be more specific about your requirements. Provide examples of allowed domains and prohibited domains. – Jeffrey Nov 05 '17 at 13:54
  • 2
    Additionally what have you tried so far? (code wise). – Kyslik Nov 05 '17 at 13:56
  • oh, thanks, didn't saw this list in docs. Checked it and didn't find anything good enough, so i guess, i'm going to write a custom rule. – CrazyWu Nov 05 '17 at 13:58
  • Examples... that's why i was looking for someting standart. Since domain names are allowed not only in english now – CrazyWu Nov 05 '17 at 13:59
  • but any was, it is a srting with allowed letters, with at least one dot – CrazyWu Nov 05 '17 at 14:00
  • You'll have to be more specific. Try finding the standard that defines how domains can be formatted. Start from there. – Jeffrey Nov 05 '17 at 14:10
  • 2
    Should your title say `validation`, instead of `eloquent`? – Don't Panic Nov 05 '17 at 14:26
  • was looking for eloquent rule, that's why wrote this title. so if there is no such rule - that's a good answer for my question. – CrazyWu Nov 05 '17 at 14:57
  • Validation rules are only for the request (e.g. the query string or POST parameters among others). You need middleware or to refine your routes list. – apokryfos Nov 05 '17 at 15:06

1 Answers1

15

I use a custom rule to check for valid FQDN.

Got the regex from another answer here @ SO, see: fully-qualified-domain-name-validation

One of the answers provides a regex, with example:

/^(?!:\/\/)(?=.{1,255}$)((.{1,63}\.){1,127}(?![0-9]*$)[a-z0-9-]+\.?)$/i

With a demo: http://regexr.com/3g5j0 which shows you the matches.

Laravel 5.5

I then created a custom rule:

<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class FQDN implements Rule
{
    /**
     * Create a new rule instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        return preg_match('/^(?!:\/\/)(?=.{1,255}$)((.{1,63}\.){1,127}(?![0-9]*$)[a-z0-9-]+\.?)$/i', $value);
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return 'Invalid FQDN.';
    }
}

And used it like this:

// ...
use App\Rules\FQDN;

// ...
$this->validate($request, [
    // other rules be here
    'fqdn' => [
        'required',
        new FQDN(),
    ],
]);

Edit for Laravel 5.4

In Laravel 5.4 you do not have the Rule contract, you can extend the validator in the AppServiceProvider, see here (or create a separate ExtendedValidationServiceProvider).

You can do this inline, but I prefer having separate classes for this.

In the ServiceProvider boot method, add:

use Illuminate\Support\Facades\Validator;

// ...

public function boot()
{
    Validator::extend('fqdn', 'App\Rules\FQDN@validate');
    Validator::replacer('fqdn', 'App\Rules\FQDN@replace');
}

Validator::extend() is for the validation rule

Validator::replacer() is for the error message

Then for the 5.4 rule class:

<?php

namespace App\Rules;

class FQDN
{
    public function validate($attribute, $value, $parameters, $validator)
    {
        return preg_match('/^(?!:\/\/)(?=.{1,255}$)((.{1,63}\.){1,127}(?![0-9]*$)[a-z0-9-]+\.?)$/i', $value);
    }

    public function replace($message, $attribute, $rule, $parameters)
    {
        return str_replace(':fqdn', implode(', ', $parameters), $message);
    }
}

Now you can use your validation like:

$this->validate($request, [
    // other rules be here
    'fqdn' => [
        'required',
        'fqdn',
    ],
]);
Robert
  • 4,840
  • 1
  • 24
  • 29
  • but i've got another strange thing here: Fatal error: Interface 'Illuminate\Contracts\Validation\Rule' after few tests with namespaces i went to laravel folder and didn't find Rule.php at all – CrazyWu Nov 05 '17 at 18:36
  • @CrazyWu which version of laravel are you using? – Robert Nov 05 '17 at 18:39
  • Ah ok.. yeah Rule contract is 5.5, let me update the answer for 5.4 – Robert Nov 05 '17 at 18:47
  • Thanks a lot. So i if got it correctly, it would work aside, after standard validation? – CrazyWu Nov 05 '17 at 19:05
  • You are extending the validator, it just adds an extra rule to your validation, which you can now use as part of your normal validation. – Robert Nov 05 '17 at 19:07
  • The regex you specified allowed strings like !@#hello.com to pass. found better domain rules here https://stackoverflow.com/questions/10306690/what-is-a-regular-expression-which-will-match-a-valid-domain-name-without-a-subd – Taher Oct 15 '18 at 13:52
  • @Smokie Yeah i copied the FQDN regex from another answer. The UTF-8 one in your link is a good one. Haven't tested it thoroughly though. – Robert Oct 15 '18 at 13:59