'Php Domain Filter Validates Invalid Domains And Invalidates Valid Domains

I trying to validate domains with php domain filter. But it's not working. Why ?

<?php

$url = 'http://stackoverflow';
$domain = parse_url($url,PHP_URL_HOST);
        
if(!filter_var($domain,FILTER_VALIDATE_DOMAIN))
{
    echo "Invalid Domain: $domain"; echo '<br>';
    echo 'LINE: ' . __LINE__;
}
else
{
    echo 'Valid Domain: ' .$domain;
    echo 'LINE: ' . __LINE__;
}

?>

I get echoed: Valid Domain: stackoverflowLINE: 15

It seems aslong as the url contains "http://" regardless if the url contains a tld or not, the php filter accepts it as a valid domain. Here's the proof ....

<?php

$url = 'stackoverflow.com';
$domain = parse_url($url,PHP_URL_HOST);
        
if(!filter_var($domain,FILTER_VALIDATE_DOMAIN))
{
    echo "Invalid Domain: $domain"; echo '<br>';
    echo 'LINE: ' . __LINE__;
}
else
{
    echo 'Valid Domain: ' .$domain;
    echo 'LINE: ' . __LINE__;
}

?>

This time, I get echoed: Invalid Domain: LINE: 10

Note the invalid domain is not getting echoed. Why ?

How to fix this ? How would you code it ?

In short, this FILTER is not working ....

filter_var($domain,FILTER_VALIDATE_DOMAIN

Thanks.



Solution 1:[1]

The output is as expected. When you try to parse an URL-like string stackoverflow.com (which isn't an URL really, because the scheme is missing), then parse_url() will treat this string as path not as host.

Therefore, the variable $domain is null and filter_var() fails as expected. You can modify your second example in a way that you add a dummy scheme if none is given:

$url = 'stackoverflow.com';
if (strpos($url, '://') === false) {
    $url = 'https://' . $url;
}
$domain = parse_url($url,PHP_URL_HOST);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 rabudde