esc_url()WP 2.8.0

Cleans the URL for use in text, changes the wrong and removes the dangerous characters.

esc_url() unlike esc_url_raw() prepares a string for displaying.

Always use esc_url() when you need to clean URLs, for example, for text or HTML attributes.

The function creates characters in the form of HTML entities, use it when creating (X)HTML or XML documents. For example, it changes the ampersand & and quotation mark ' for their HTML entities &#038, &#039.

Avoid URLs without protocol. Every URL must begin with http, https, ftp, ftps, mailto, news, irc, gopher, nntp, feed or telnet

1 time — 0.000052 sec (very fast) | 50000 times — 0.31 sec (very fast) | PHP 7.1.2, WP 4.7.3
Hooks from the function

Return

String. The cleaned URL after the clean_url filter is applied. An empty string is returned if $url specifies a protocol other than those in $protocols, or if $url contains an empty string.

Usage

esc_url( $url, $protocols, $_context );
$url(string) (required)
The URL to be cleaned.
$protocols(array)
An array of acceptable protocols. By default: http, https, ftp, ftps, mailto, news, irc, gopher, nntp, feed, telnet.
Default: null
$_context(string)

How the URL will be used. May be:

  • display - ampersand ( & ) and quotes (') will be replaced with HTML entities.
  • db - standard sanitize.
  • '' - standard sanitize.

Default: 'display'

Examples

0

#1 Basic Example

$url = "http;//example.com/link?var='some&";
echo esc_url( $url ); //> http://example.com/link?var=&#039some&#038

$url = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAD///////neHiwAAAAF3RST/+8RwZ==';
echo esc_url( $url ); //> ''

echo esc_url( '#some' ); //> #some

var_dump( esc_url( '' ) );    // string(0) ""
var_dump( esc_url( false ) ); // string(0) ""
var_dump( esc_url( null ) );  // string(0) ""
0

#2 Relative URL

echo esc_url( '/foo' ); //> /foo
0

#3 Comparison with urlencode()

  • urlencode() - encodes the passed string so that it can be used as part of the URL (without the domain). If you pass the whole URL, it becomes unusable.

  • esc_url() - handles the whole URL (does not break it), takes care of the safe display of the URL - it removes or changes some characters in the URL (not like urlencode() does).
$url = "http://example.com/моя ссылка?var='some&";

echo esc_url( $url );   // http://example.com/моя%20ссылка?var='some&
echo urlencode( $url ); // http%3A%2F%2Fexample.com%2F%D0%BC%D0%BE%D1%8F+%D1%81%D1%81%D1%8B%D0%BB%D0%BA%D0%B0%3Fvar%3D%27some%26

Changelog

Since 2.8.0 Introduced.

esc_url() code WP 6.5.3

function esc_url( $url, $protocols = null, $_context = 'display' ) {
	$original_url = $url;

	if ( '' === $url ) {
		return $url;
	}

	$url = str_replace( ' ', '%20', ltrim( $url ) );
	$url = preg_replace( '|[^a-z0-9-~+_.?#=!&;,/:%@$\|*\'()\[\]\\x80-\\xff]|i', '', $url );

	if ( '' === $url ) {
		return $url;
	}

	if ( 0 !== stripos( $url, 'mailto:' ) ) {
		$strip = array( '%0d', '%0a', '%0D', '%0A' );
		$url   = _deep_replace( $strip, $url );
	}

	$url = str_replace( ';//', '://', $url );
	/*
	 * If the URL doesn't appear to contain a scheme, we presume
	 * it needs http:// prepended (unless it's a relative link
	 * starting with /, # or ?, or a PHP file).
	 */
	if ( ! str_contains( $url, ':' ) && ! in_array( $url[0], array( '/', '#', '?' ), true ) &&
		! preg_match( '/^[a-z0-9-]+?\.php/i', $url )
	) {
		$url = 'http://' . $url;
	}

	// Replace ampersands and single quotes only when displaying.
	if ( 'display' === $_context ) {
		$url = wp_kses_normalize_entities( $url );
		$url = str_replace( '&', '&', $url );
		$url = str_replace( "'", ''', $url );
	}

	if ( str_contains( $url, '[' ) || str_contains( $url, ']' ) ) {

		$parsed = wp_parse_url( $url );
		$front  = '';

		if ( isset( $parsed['scheme'] ) ) {
			$front .= $parsed['scheme'] . '://';
		} elseif ( '/' === $url[0] ) {
			$front .= '//';
		}

		if ( isset( $parsed['user'] ) ) {
			$front .= $parsed['user'];
		}

		if ( isset( $parsed['pass'] ) ) {
			$front .= ':' . $parsed['pass'];
		}

		if ( isset( $parsed['user'] ) || isset( $parsed['pass'] ) ) {
			$front .= '@';
		}

		if ( isset( $parsed['host'] ) ) {
			$front .= $parsed['host'];
		}

		if ( isset( $parsed['port'] ) ) {
			$front .= ':' . $parsed['port'];
		}

		$end_dirty = str_replace( $front, '', $url );
		$end_clean = str_replace( array( '[', ']' ), array( '%5B', '%5D' ), $end_dirty );
		$url       = str_replace( $end_dirty, $end_clean, $url );

	}

	if ( '/' === $url[0] ) {
		$good_protocol_url = $url;
	} else {
		if ( ! is_array( $protocols ) ) {
			$protocols = wp_allowed_protocols();
		}
		$good_protocol_url = wp_kses_bad_protocol( $url, $protocols );
		if ( strtolower( $good_protocol_url ) !== strtolower( $url ) ) {
			return '';
		}
	}

	/**
	 * Filters a string cleaned and escaped for output as a URL.
	 *
	 * @since 2.3.0
	 *
	 * @param string $good_protocol_url The cleaned URL to be returned.
	 * @param string $original_url      The URL prior to cleaning.
	 * @param string $_context          If 'display', replace ampersands and single quotes only.
	 */
	return apply_filters( 'clean_url', $good_protocol_url, $original_url, $_context );
}