11

WordPress provides a helpful function called is_email() which checks if a given email address is valid. Is there a similar function available to check if a URL is valid?

I tried is_url() but that was just wishful thinking on my part.

Ref: http://codex.wordpress.org/Function_Reference/is_email

12

Use the native php function Filter Validator

if (filter_var($url, FILTER_VALIDATE_URL) === FALSE) {
    die('Not a valid URL');
}
5
  • Nice one and thanks @shanebp - never knew that filter existed! Oct 24 '14 at 17:01
  • 2
    FILTER_VALIDATE_URL looks good but has some serious problems: d-mueller.de/blog/…
    – tobltobs
    Oct 6 '15 at 16:13
  • 1
    @tobltobs: Those are not problems, they are features. The author is complaining that valid URLs are being reported as valid. That's like complaining that PDO is broken because is allows $pdo->query("SELECT pw FROM users WHERE id={$_GET['id']}").
    – dotancohen
    Jul 8 '18 at 14:35
  • You may be right @dotancohen, that those are technically valid URLs. So maybe the problem is really in our question. We're not just wanting "technically valid URLs", we're wanting "safe URLs". eg, URLs that help prevent XSS attacks or other mischief. @orionrush's suggestion avoids a number of those problems, whereas FILTER_VALIDATE_URL does not. Sep 3 '18 at 17:51
  • Your way validates ttps://www.youtube.com as valid. In other word - do not use FILTER_VALIDATE_URL - it is unreliable.
    – Jeffz
    May 17 '20 at 13:40
6

I know this is an old post, but for anyone visiting it's also worth considering the WP functions esc_url() and esc_url_raw(), the latter being safe for databases entries etc, as it does not encode entities. esc_url() does encode entities and so is good for display to users.

In the source you can see that esc_url() checks for a whitelist of allowed protocols and structure and so avoids some of the vulnerabilities of FILTER_VALIDATE_URL noted by the link posed by @tobltobs.

5

I found wp_http_validate_url quite convenient to check if a string in valid URL or not while working on my project.

Take a reference from here: https://developer.wordpress.org/reference/functions/wp_http_validate_url/

For example:

$val = 'http://somevalidurl.com';
if ( wp_http_validate_url( $val ) ) {

    // It's valid URL;

} else {

    // It's NOT valid URL;

}

It returns the URL itself if it's valid,else false.

4
  • This function sounds great, but I think it made a few mistakes with regards to user-submitted data. It found the URL localhost to be invalid; but it found http://example.com/"><script>alert("xss")</script> to be valid. Sep 3 '18 at 17:57
  • sorry, SO isn't letting me modify my comment. I meant it finds http://localhost invalid. Sep 3 '18 at 18:05
  • 1
    @thespacecamel You can use http_request_host_is_external filter to allow localhost: function allow_some_url( $external, $host, $url ) { return ( $host === 'localhost' ) ? true : $external; } add_filter( 'http_request_host_is_external', 'allow_some_url', 10, 3 ); if ( wp_http_validate_url( 'http://localhost/wordpress/' ) ) { echo 'valid'; } else { echo 'invalid'; } Sep 4 '18 at 11:33
  • Keep in mind it can be a bit slow, since it uses gethostbyname() to get the IP of the URL to make further assertions. Jan 19 '20 at 21:50
1

In my opinion is better to use wp_http_validate_url.

Example 1:

filter_var( '//website.com', FILTER_VALIDATE_URL )

Return false.

Example 2:

wp_http_validate_url( '//website.com' )

Return url.

  1. When you don't know is website use https or http protocol, it's better to use '//'.
  2. wp_http_validate_url is improved by WP developers (is more specific).
  3. Theoretically you can use some hooks (filters & actions) for wp_http_validate_url. You can't use hooks for filter_var.

Ref: https://developer.wordpress.org/reference/functions/wp_http_validate_url/

Ref: https://www.php.net/manual/en/function.filter-var.php

1
  • I agree, wp_http_validate_url() is a better validator, allowing for IP addresses as well as forcing an extra validation for localhost URL with the filter http_request_host_is_external which by default returns false as an added safety measure
    – Aurovrata
    Sep 30 at 16:13
1

Let's discuss our options for validating URLs in WordPress starting with the obvious ones.

  1. filter_var() with the FILTER_VALIDATE_URL filter in PHP doesn't work for internationalized domain names containing non-ASCII characters such as http://스타벅스코리아.com. It also has some other issues, as discussed by David Müller, like accepting http://example.com/"><script>alert("xss")</script> as valid URL even though it is clearly malicious.

  2. wp_http_validate_url() in WordPress may do a better job even though it was intended specifically for using in HTTP API and not for the general validation of URLs. But it still doesn't solve the two specific issues discussed earlier.

  3. preg_match() in PHP may work for you or it may not. Writing regular expressions forecasting every possible scenario is not always the most ideal solution and getting it universally right may not be possible from time to time.

  4. esc_url_raw() in WordPress is not intended for validating URLs but it seems to be doing a better job than the others. It will work for non-ASCII characters as well as solve the other issues discussed earlier. This function will basically sanitize any string for saving in the WordPress database as a URL by removing or altering any characters that are either invalid or malicious. And therefore, if the sanitized version isn't the same as the unsanitized version, it can be pretty confidently said that the URL isn't valid and maybe most importantly not safe.

Here is how the URL verification can be done with the esc_url_raw() function by also taking advantage of the strtolower() function to make the verification case insensitive.

function validateUrl($url) {
    if ( strtolower(esc_url_raw($url)) === strtolower($url) ) {
        return $url;
    } else {
        return false;
    }
}
-1

To ensure user-submitted URL is valid and safe to store and later display, I suggest

esc_url_raw($url) === $url

esc_url_raw(), like @orionrush mentioned above, sanitizes the URL by removing anything invalid or malicious from it. So, if there string has nothing invalid or malicious, then it's ok.

Eg

if( esc_url_raw($url) === $url ) {
   // URL is valid. Use it...
} else {
   // URL is invalid or malicious. Don't use it...
}

I wrote a longer blog post on that here: https://cmljnelson.wordpress.com/2018/08/31/url-validation-in-wordpress/

1
  • this only validates the char string, it does not differentiate between the strings my-domain and http://my-domain.com/?id=1 2 3, in the latter case your example would invalidate a perfectly valid url.
    – Aurovrata
    Sep 30 at 14:19
-2

is_email(), actually do not check if an email address is valid, only if it is conforming to spec. The email I gladly supply for many sites that show pointless interest in my email address is a@b.com which is conforming address but it is unlikely to have anyone using it.

Checking out urls is best done by pinging them. You can try to check conformance, but in theory there are very little limitation to what an encoded url can be.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.