Search code examples
phpvalidationurl

PHP valid url, including subdomains and also subpath


I need to check if a given string is valid. For me, the following and any other similar combinations are all valid URLs

'https://example.com/api/',
'https://www.example.com/test-subpath',
'https://www.example.com',
'example.com/test/page',
'www.example.com',
'www.subdomain.example.com',
'https://www.subdomain.example.com',
'subdomain.example.com',
'http://subdomain.example.com',
'https://subdomain.example.com'

while

'user-service/api/'

is invalid. I tried parse_url() and filter_var($url, FILTER_VALIDATE_URL) methods but non worked.

Thanks in advance.


Solution

  • Your script and the filter method works as expected. As www.example.com is just a hostname and only a part of a URL, it needs to return false.

    The definition of a URL sais

    <scheme>:<scheme-specific-part>
    

    In your case, you may apply following ruleset

    (Demo: https://3v4l.org/oX2as)

    • Check if the URL is valid
      • yes -> return true
      • no -> add the scheme and check again
        • yes -> return true
        • no -> validation failed

    As already stated in the comments, it is no good idea to use a regex, which may come over complicated to check for all rules, or write custom functions, i.e. with missing check for charsets.

    Use whenever possible well known and tested supplied PHP functions.

    $urls = [
        'https://example.com/api/',
        'https://www.example.com/test-subpath',
        'https://www.example.com',
        'example.com/test/page',
        'www.example.com',
        'www.subdomain.example.com',
        'https://www.subdomain.example.com',
        'subdomain.example.com',
        'http://subdomain.example.com',
        'https://subdomain.example.com',
    ];
    
    function checkUrl(string $url): bool
    {
        return (bool)filter_var($url, FILTER_VALIDATE_URL);
    }
    
    foreach ($urls as $url) {
        if (checkUrl($url)) {
            echo $url . ' is a valid URL', PHP_EOL;
            continue;
        }
    
        $urlWithProtocol = 'https://' . $url;
        if (checkUrl($urlWithProtocol)) {
            echo $urlWithProtocol, ' with added protocol is a valid URL', PHP_EOL;
            continue;
        }
    
        echo $url, ' is not a valid URL', PHP_EOL;
    }
    

    will result in

    https://example.com/api/ is a valid URL
    https://www.example.com/test-subpath is a valid URL
    https://www.example.com is a valid URL
    https://example.com/test/page with added protocol is a valid URL
    https://www.example.com with added protocol is a valid URL
    https://www.subdomain.example.com with added protocol is a valid URL
    https://www.subdomain.example.com is a valid URL
    https://subdomain.example.com with added protocol is a valid URL
    http://subdomain.example.com is a valid URL
    https://subdomain.example.com is a valid URL