wp_kses_hair() │ WP 1.0.0
Gets a list of HTML tag attributes (as an array) from the provided string with attributes.
This function does a lot of work. In addition to processing the string and creating an array of the attributes contained in it, it also adds quotes if they are not specified in the attributes. Additionally, it removes unspecified, thus prohibited protocols (http ) from the attribute values if it is a URL. It also removes duplicate attributes, so that foo=bar foo=baz becomes foo="bar".
Although the function relates to cleaning functions (kses), it is convenient to use in plugins when it is necessary to process tag attributes, which is often needed.
1 time — 0.000145 sec (fast) | 50000 times — 2.85 sec (fast)
No Hooks.
Returns
Array[] . A list of obtained attributes as an array describing each attribute. Or an empty array if nothing could be obtained.
Usage
wp_kses_hair( $attr, $allowed_protocols );
$attr(string) (required)
HTML tag attributes, exactly as they are specified in the attribute. Multiple spaces are ignored.
$allowed_protocols(array) (required)
Allowed protocols that should be retained if there are URLs in the attribute values.
Examples
$attrs = wp_kses_hair(' src="http://example.com/jpg.jpg" alt="aaaaa" foo=bar', 'http');
/*
$attrs will contain:
Array
(
[src] => Array
(
[name] => src
[value] => http://example.com/jpg.jpg
[whole] => src="http://example.com/jpg.jpg"
[vless] => n
)
[alt] => Array
(
[name] => alt
[value] => aaaaa
[whole] => alt="aaaaa"
[vless] => n
)
[foo] => Array
(
[name] => foo
[value] => bar
[whole] => foo="bar"
[vless] => n
)
)
*/
#2 Protocol, which is different from the value of the attribute
If you specify a protocol that will be different, the function simply removes the protocol leaving the URL relative:
$attrs = wp_kses_hair('src=http://example.com/jpg.jpg', 'https');
/*
We get it:
Array
(
[src] => Array
(
[name] => src
[value] => //example.com/jpg.jpg
[whole] => src="//example.com/jpg.jpg"
[vless] => n
)
)
*/
Add Your Own Example
Changelog
wp_kses_hair() wp kses hair code
WP 6.9.1
function wp_kses_hair( $attr, $allowed_protocols ) {
$attrarr = array();
$mode = 0;
$attrname = '';
$uris = wp_kses_uri_attributes();
// Loop through the whole attribute list.
while ( strlen( $attr ) !== 0 ) {
$working = 0; // Was the last operation successful?
switch ( $mode ) {
case 0:
if ( preg_match( '/^([_a-zA-Z][-_a-zA-Z0-9:.]*)/', $attr, $match ) ) {
$attrname = $match[1];
$working = 1;
$mode = 1;
$attr = preg_replace( '/^[_a-zA-Z][-_a-zA-Z0-9:.]*/', '', $attr );
}
break;
case 1:
if ( preg_match( '/^\s*=\s*/', $attr ) ) { // Equals sign.
$working = 1;
$mode = 2;
$attr = preg_replace( '/^\s*=\s*/', '', $attr );
break;
}
if ( preg_match( '/^\s+/', $attr ) ) { // Valueless.
$working = 1;
$mode = 0;
if ( false === array_key_exists( $attrname, $attrarr ) ) {
$attrarr[ $attrname ] = array(
'name' => $attrname,
'value' => '',
'whole' => $attrname,
'vless' => 'y',
);
}
$attr = preg_replace( '/^\s+/', '', $attr );
}
break;
case 2:
if ( preg_match( '%^"([^"]*)"(\s+|/?$)%', $attr, $match ) ) {
// "value"
$thisval = $match[1];
if ( in_array( strtolower( $attrname ), $uris, true ) ) {
$thisval = wp_kses_bad_protocol( $thisval, $allowed_protocols );
}
if ( false === array_key_exists( $attrname, $attrarr ) ) {
$attrarr[ $attrname ] = array(
'name' => $attrname,
'value' => $thisval,
'whole' => "$attrname=\"$thisval\"",
'vless' => 'n',
);
}
$working = 1;
$mode = 0;
$attr = preg_replace( '/^"[^"]*"(\s+|$)/', '', $attr );
break;
}
if ( preg_match( "%^'([^']*)'(\s+|/?$)%", $attr, $match ) ) {
// 'value'
$thisval = $match[1];
if ( in_array( strtolower( $attrname ), $uris, true ) ) {
$thisval = wp_kses_bad_protocol( $thisval, $allowed_protocols );
}
if ( false === array_key_exists( $attrname, $attrarr ) ) {
$attrarr[ $attrname ] = array(
'name' => $attrname,
'value' => $thisval,
'whole' => "$attrname='$thisval'",
'vless' => 'n',
);
}
$working = 1;
$mode = 0;
$attr = preg_replace( "/^'[^']*'(\s+|$)/", '', $attr );
break;
}
if ( preg_match( "%^([^\s\"']+)(\s+|/?$)%", $attr, $match ) ) {
// value
$thisval = $match[1];
if ( in_array( strtolower( $attrname ), $uris, true ) ) {
$thisval = wp_kses_bad_protocol( $thisval, $allowed_protocols );
}
if ( false === array_key_exists( $attrname, $attrarr ) ) {
$attrarr[ $attrname ] = array(
'name' => $attrname,
'value' => $thisval,
'whole' => "$attrname=\"$thisval\"",
'vless' => 'n',
);
}
// We add quotes to conform to W3C's HTML spec.
$working = 1;
$mode = 0;
$attr = preg_replace( "%^[^\s\"']+(\s+|$)%", '', $attr );
}
break;
} // End switch.
if ( 0 === $working ) { // Not well-formed, remove and try again.
$attr = wp_kses_html_error( $attr );
$mode = 0;
}
} // End while.
if ( 1 === $mode && false === array_key_exists( $attrname, $attrarr ) ) {
/*
* Special case, for when the attribute list ends with a valueless
* attribute like "selected".
*/
$attrarr[ $attrname ] = array(
'name' => $attrname,
'value' => '',
'whole' => $attrname,
'vless' => 'y',
);
}
return $attrarr;
}
Related Functions