函数文档

wp_kses()

💡 云策文档标注

概述

wp_kses() 是 WordPress 中用于过滤文本内容并移除不允许的 HTML 的函数,确保只有允许的 HTML 元素、属性、属性值和实体出现在输出中。它常用于安全地处理用户输入或动态内容,防止跨站脚本(XSS)攻击。

关键要点

  • 函数核心功能:过滤文本,仅保留允许的 HTML 元素和属性,移除恶意脚本。
  • 参数说明:$content 为要过滤的文本(需未转义),$allowed_html 指定允许的 HTML 元素和属性(可以是数组或上下文如 'post'),$allowed_protocols 指定允许的 URL 协议(默认来自 wp_allowed_protocols())。
  • 相关函数:wp_kses_post() 用于过滤文章内容,wp_kses_allowed_html() 提供默认允许的 HTML 列表。
  • 安全注意事项:默认不允许 javascript 协议,以防止未信任用户的攻击。
  • KSES 含义:递归缩写,代表“KSES Strips Evil Scripts”,源自 XSS 和 access。

代码示例

// 示例:使用 wp_kses() 过滤内容,只允许特定 HTML 标签
$str = 'Check Kses function I am <strong>stronger</strong> and <a href="http://example.com">cooler</a> every single day <br />Click Here';
$arr = array( 'br' => array(), 'p' => array(), 'strong' => array() );
echo wp_kses( $str, $arr ); // 输出中只保留 strong、br、p 标签,a 标签被移除

注意事项

  • 属性值在数组中通常设置为 true 而非空数组,例如 'href' => true。
  • 对于 SVG 等自定义 HTML,需注意属性名需小写(如 viewBox 应写为 viewbox),否则可能被过滤。
  • 可通过 safe_style_css 过滤器添加允许的 CSS 样式属性。

📄 原文内容

Filters text content and strips out disallowed HTML.

Description

This function makes sure that only the allowed HTML element names, attribute names, attribute values, and HTML entities will occur in the given text string.

This function expects unslashed data.

See also

Parameters

$contentstringrequired
Text content to filter.
$allowed_htmlarray[]|stringrequired
An array of allowed HTML elements and attributes, or a context name such as 'post'. See wp_kses_allowed_html() for the list of accepted context names.
$allowed_protocolsstring[]optional
Array of allowed URL protocols.
Defaults to the result of wp_allowed_protocols() .

Default:array()

Return

string Filtered content containing only the allowed HTML.

More Information

KSES is a recursive acronym which stands for “KSES Strips Evil Scripts”.

For parameter $allowed_protocols, the default allowed protocols are http, https, ftp, mailto, news, irc, gopher, nntp, feed, and telnet. This covers all common link protocols, except for javascript, which should not be allowed for untrusted users.

Source

function wp_kses( $content, $allowed_html, $allowed_protocols = array() ) {
	if ( empty( $allowed_protocols ) ) {
		$allowed_protocols = wp_allowed_protocols();
	}

	$content = wp_kses_no_null( $content, array( 'slash_zero' => 'keep' ) );
	$content = wp_kses_normalize_entities( $content );
	$content = wp_kses_hook( $content, $allowed_html, $allowed_protocols );

	return wp_kses_split( $content, $allowed_html, $allowed_protocols );
}

Changelog

Version Description
1.0.0 Introduced.

User Contributed Notes

  1. Skip to note 10 content

    Many function names in WordPress are self-explanatory and if they aren’t, their documentation usually sheds some light on how they got their name. I find this makes it easier to later recall their names and uses. However, wp_kses is an exception. So for anyone else wondering:

    kses comes from the terms XSS (cross-site scripting) and access. It’s also a recursive acronym (every open-source project should have one!) for “kses strips evil scripts”.

  2. Skip to note 11 content

    Allowed HTML tags array
    This is an example of how to format an array of allowed HTML tags and attributes.

    array(
        'a' => array(
            'href' => array(),
            'title' => array()
        ),
        'br' => array(),
        'em' => array(),
        'strong' => array(),
    );

  3. Skip to note 12 content

    WordPress wp_kses is an HTML filtering mechanism. If you need to escape your output in a specific (custom) way, wp_kses function in WordPress will come handy.

    stronger</strong> and cooler every single day <a href="#" rel="nofollow ugc">Click Here</a>';
    echo $str;
    $arr = array( 'br' => array(), 'p' => array(), 'strong' => array() );
    echo 'String using wp_kses function....' . wp_kses( $str, $arr );
    ?>

    Output:
    Before wp_kses: Check Kses function I am stronger and cooler every single day Click Here
    After wp_kses: String using wp_kses function…. Check Kses function I am stronger and cooler every single day Click Here

    It will display a resultant string as shown in the output screen. It only reflects the allowed tags strong, br, p as defined in wp_kses function and anchor tag is removed. So, no link for click Here text is formed.

  4. Skip to note 14 content

    // Allowed img tag and support svg base64 data like:  <img src="data:image/svg+xml;base64,__base64_code__" />
    function wpdocs_allowed_html() {
    	return array(
    		'img' => array(
    			'title' => array(),
    			'src'	=> array(),
    			'alt'	=> array(),
    		)
    	);
    }
    
    function wpdocs_allowed_protocols() {
    	return array(
    		'data' 	=> array(),
    		'http'	=> array(),
    		'https' => array(),
    	);
    }
    
    function wpdocs_output_img() {
    	$html = '';
    	ob_start();
    	?>
    
    	<img src="data:image/svg+xml;base64,Your_base64_code" title="img_title" alt="alt_info" />
    
    	</pre>
    				</div><!-- .comment-content -->
    
    					<section id='feedback-5574' class='wporg-has-embedded-code feedback hide-if-js' data-comment-count='1'>
    <ul class='children'>
    			<li id="comment-7370" data-comment-id="7370" class="comment byuser comment-author-sirlouen odd alt depth-2">
    			<article id="div-comment-7370" class="comment-body">
    
    			
    				<div class="wporg-has-embedded-code comment-content" id="comment-content-7370">
    				<div>No need to do a function to return an array, to then assign the return of the function to a variable.</div>
    <div><a href="https://profiles.wordpress.org/sirlouen/" rel="external nofollow" class="url">Manuel Camargo</a> <a class="comment-date" href="https://developer.wordpress.org/reference/functions/wp_kses/#comment-7370"><time datetime="2025-07-22T09:58:10+00:00">9 months ago</time></a></div>
    				</div><!-- .comment-content -->
    
    						</article>
    			</li>
    					</ul>
    </section><!-- .feedback -->
    <footer class='feedback-links wporg-dot-link-list' >
    <a role="button" class="feedback-login" href="https://login.wordpress.org/?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fwp_kses%2F%3Freplytocom%3D5574%23feedback-editor-5574" rel="nofollow">Log in to add feedback</a></footer>
    </article><!-- .comment-body -->
    </li>
    			<li id="comment-6252" data-comment-id="6252" class="comment byuser comment-author-renehermi even thread-even depth-1">
    			<article id="div-comment-6252" class="comment-body">
    
    							<a href="#comment-content-6252" class="screen-reader-text">Skip to note 15 content</a>
    				<header class="comment-meta">
    					<div class="comment-author vcard">
    						<span class="comment-author-attribution">
    						<a href="https://profiles.wordpress.org/renehermi/" rel="external nofollow" class="url">Rene Hermenau</a>						</span>
    						<a class="comment-date" href="https://developer.wordpress.org/reference/functions/wp_kses/#comment-6252">
    							<time datetime="2022-12-22T14:46:35+00:00">
    							3 years ago							</time>
    						</a>
    
    																													</div>
    					<div class="user-note-voting" data-nonce="778e0c1b29" data-can-vote="false"><a class="user-note-voting-up" title="You must log in to vote on the helpfulness of this note" data-id="6252" data-vote="up" href="https://login.wordpress.org?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fwp_kses%2F%23comment-6252"><span class="screen-reader-text">You must log in to vote on the helpfulness of this note</span></a><span class="user-note-voting-count " title="100% like this"><span class="screen-reader-text">Vote results for this note: </span>1</span><a class="user-note-voting-down" title="You must log in to vote on the helpfulness of this note" data-id="6252" data-vote="down" href="https://login.wordpress.org?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fwp_kses%2F%23comment-6252"><span class="screen-reader-text">You must log in to vote on the helpfulness of this note</span></a></div>				</header>
    				<!-- .comment-metadata -->
    			
    				<div class="wporg-has-embedded-code comment-content" id="comment-content-6252">
    				<p>If you want to keep certain style properties you have to use another filter.<br />
    Unortunately wp_kses will check the style properties against a list of allowed properties and it will still strip the style attribute if none of the styles are safe. </p>
    <p>E.g. Use this filter if you want to keep the `display` property within a `style`:<br />
    a</p>
    <pre class="wp-block-code"><code lang="php" class="language-php ">add_filter( 'safe_style_css', function( $styles ) {
        $styles[] = 'display';
        return $styles;
    } );

    Check kses.php for default:
    https://core.trac.wordpress.org/browser/trunk/src/wp-includes/kses.php

  5. Skip to note 16 content

    Sanitize SVG markup for front-end display using wp_kses, and a list of allowed HTML elements and attributes specific to a SVG tag.

    /**
    * Sanitize SVG markup for front-end display.
    *
    * @param  string $svg SVG markup to sanitize.
    * @return string 	  Sanitized markup.
    */
    function prefix_sanitize_svg( $svg = '' ) {
    	$allowed_html = [
    		'svg'  => [
    			'xmlns'       => [],
    			'fill'        => [],
    			'viewbox'     => [],
    			'role'        => [],
    			'aria-hidden' => [],
    			'focusable'   => [],
    			'height'      => [],
    			'width'       => [],
    		],
    		'path' => [
    			'd'    => [],
    			'fill' => [],
    		],
    	];
    
    	return wp_kses( $svg, $allowed_html );
    }

  6. Skip to note 17 content

    If you are using wp_kses to escape SVG, be warned `wp_kses() ` will strip camelcased attributes in your args. Make sure your args are converted to lowercase for their uppercase equivalents. For example:

    $args = array(
    	'svg'            => array(
    		'viewbox'             => true, // viewBox
    		'preserveaspectratio' => true, // preserveAspectRatio
    	),
    	'lineargradient' => array(             // linearGradient
    		'gradientunits'     => true,   // gradientUnits
    		'gradienttransform' => true,   // gradientTransform
    		'spreadmethod'      => true,   // spreadMethod
    	),
    );