wp_specialchars_decode()WP 2.8.0

Converts (decodes) HTML entities to their HTML characters. Changes only: &, <, >, ", '

If you need to encode characters into entities instead, use esc_html()

Keep in mind that this function does not decode all entities. For example, it does not decode &#8211 (–).

If you need to decode all characters, use html_entity_decode().

1 time — 0.000094 sec (very fast) | 50000 times — 1.08 sec (fast)

No Hooks.

Returns

String. Decoded text without HTML entities.

Usage

wp_specialchars_decode( $string, $quote_style );
$string(string) (required)
The text to be processed.
$quote_style(string/int)

Determines how to decode quotes. Can be:

  • ENT_COMPAT or 'double' — change only double quotes: ".
  • ENT_QUOTES — change both types of quotes: " and '.
  • 'single' — change only single quotes: '.
  • ENT_NOQUOTES — does not touch quotes at all.

Default: ENT_NOQUOTES

Examples

0

#1 Replace HTML entities with familiar HTML characters

$string = <<<'TEXT'
ampersand - &amp; / &#038; / &#x26;
single quotes - &#039; / &#x27;
double quotation marks - &quot; / &#034; / &#x22;
more - &gt; / &#062;
less - &lt; / &#060;
TEXT;

echo wp_specialchars_decode( $string, ENT_QUOTES );

/* will output:
ampersand - & / & / &
single quotes - ' / '
double quotes - " / " / "
more - > / >
less - < / <
*/

Beware that this function does not decode all entities. For example, it does not decode &#8211 (–).

If you encounter such an issue, try using html_entity_decode().

Changelog

Since 2.8.0 Introduced.

wp_specialchars_decode() code WP 6.9.1

function wp_specialchars_decode( $text, $quote_style = ENT_NOQUOTES ) {
	$text = (string) $text;

	if ( 0 === strlen( $text ) ) {
		return '';
	}

	// Don't bother if there are no entities - saves a lot of processing.
	if ( ! str_contains( $text, '&' ) ) {
		return $text;
	}

	// Match the previous behavior of _wp_specialchars() when the $quote_style is not an accepted value.
	if ( empty( $quote_style ) ) {
		$quote_style = ENT_NOQUOTES;
	} elseif ( ! in_array( $quote_style, array( 0, 2, 3, 'single', 'double' ), true ) ) {
		$quote_style = ENT_QUOTES;
	}

	// More complete than get_html_translation_table( HTML_SPECIALCHARS ).
	$single      = array(
		'&#039;' => '\'',
		'&#x27;' => '\'',
	);
	$single_preg = array(
		'/&#0*39;/'   => '&#039;',
		'/&#x0*27;/i' => '&#x27;',
	);
	$double      = array(
		'&quot;' => '"',
		'&#034;' => '"',
		'&#x22;' => '"',
	);
	$double_preg = array(
		'/&#0*34;/'   => '&#034;',
		'/&#x0*22;/i' => '&#x22;',
	);
	$others      = array(
		'&lt;'   => '<',
		'&#060;' => '<',
		'&gt;'   => '>',
		'&#062;' => '>',
		'&amp;'  => '&',
		'&#038;' => '&',
		'&#x26;' => '&',
	);
	$others_preg = array(
		'/&#0*60;/'   => '&#060;',
		'/&#0*62;/'   => '&#062;',
		'/&#0*38;/'   => '&#038;',
		'/&#x0*26;/i' => '&#x26;',
	);

	if ( ENT_QUOTES === $quote_style ) {
		$translation      = array_merge( $single, $double, $others );
		$translation_preg = array_merge( $single_preg, $double_preg, $others_preg );
	} elseif ( ENT_COMPAT === $quote_style || 'double' === $quote_style ) {
		$translation      = array_merge( $double, $others );
		$translation_preg = array_merge( $double_preg, $others_preg );
	} elseif ( 'single' === $quote_style ) {
		$translation      = array_merge( $single, $others );
		$translation_preg = array_merge( $single_preg, $others_preg );
	} elseif ( ENT_NOQUOTES === $quote_style ) {
		$translation      = $others;
		$translation_preg = $others_preg;
	}

	// Remove zero padding on numeric entities.
	$text = preg_replace( array_keys( $translation_preg ), array_values( $translation_preg ), $text );

	// Replace characters according to translation table.
	return strtr( $text, $translation );
}