Skip to content

Instantly share code, notes, and snippets.

@CodeAlDente
Created June 15, 2022 04:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CodeAlDente/2eda0ce9a25b098f3d3484cdccc83f0a to your computer and use it in GitHub Desktop.
Save CodeAlDente/2eda0ce9a25b098f3d3484cdccc83f0a to your computer and use it in GitHub Desktop.
Validate domain names in PHP out-of-the-box
<?php
function validateDomain(string $domain) :bool {
/**
* First remove any whitespaces and set string to lowercase.
*/
$domain = trim($domain);
$domain = mb_strtolower($domain, "UTF-8");
/**
* Now treat input as threat as it could just come from an input field.
* We need to sanitize it. For this we use PHP to strip out every
* character that shouldn't be in a domain name.
*/
$domain = htmlspecialchars($domain);
/**
* For the next steps we convert the string into punycode so we can handle
* domain names with non-lating characters better.
*/
$domain = idn_to_ascii($domain);
/**
* Now let's run the first main validation to check for valid length and characters.
* Only valid strings will remain after this, otherwise $domain is now false.
*/
$domain = filter_var($domain, FILTER_VALIDATE_DOMAIN);
/**
* Check if string input already failed
*/
if (!$domain) {
return false;
}
/**
* From here on we now use a second validation for email address. This in combination with
* previous checks will make sure the string is most likely a valid domain name.
*/
$domain = filter_var("foobar@" . $domain, FILTER_VALIDATE_EMAIL);
/**
* Check again if string input failed
*/
if (!$domain) {
return false;
}
/**
* String passed all checks. It's most likely a valid domain name!
*/
return true;
}
@CodeAlDente
Copy link
Author

[ ] => bool(false) // whitespace only
[] => bool(false) // empty value
[-] => bool(false) // dash only
[.] => bool(false) // dot only
[..] => bool(false) // two dots only
[.example.com] => bool(false) // starting with dot
[<script] => bool(false) // malicious code #1
[alert(] => bool(false) // malicious code #2
[ example.com] => bool(false) // whitespace at the start
[exam ple.com] => bool(true) // whitespace between
[example.com ] => bool(true) // whitespace at the end
[example.com] => bool(false) // valid domain name
[localhost] => bool(true) // valid domain name
[sub.example.co.uk] => bool(true) // valid sub-domain, actually multi-level-domain
[xn--fsqu00a.xn--0zwm56d] => bool(true) // valid domain already in punycode format

@CodeAlDente
Copy link
Author

Run new checks easily

<?php

$strings = [
    "example.com",
];

foreach ($strings as $string) {
    echo "[$string] => " . var_dump(validateDomain($string));
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment