note 118485 added to function.strip-tags
| From: | Trititaty | Date: | Mon, 14 Dec 2015 09:28:43 +0000 |
| Subject: | note 118485 added to function.strip-tags | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-204345@lists.php.net to get a copy of this message | ||
Features:
* allowable tags (as in strip_tags),
* optional stripping attributes of the allowable tags,
* optional comment preserving,
* deleting broken and unclosed tags and comments,
* optional callback function call for every piece processed allowing for flexible replacements.
<?php
function better_strip_tags( $str, $allowable_tags = '', $strip_attrs = false,
$preserve_comments = false, callable $callback = null ) {
$allowable_tags = array_map( 'strtolower', array_filter( // lowercase
preg_split( '/(?:>|^)\\s*(?:<|$)/', $allowable_tags, -1, PREG_SPLIT_NO_EMPTY
), // get tag names
function( $tag ) { return preg_match( '/^[a-z][a-z0-9_]*$/i', $tag ); } // filter
broken
) );
$comments_and_stuff = preg_split( '/(<!--.*?(?:-->|$))/', $str, -1,
PREG_SPLIT_DELIM_CAPTURE );
foreach ( $comments_and_stuff as $i => $comment_or_stuff ) {
if ( $i % 2 ) { // html comment
if ( !( $preserve_comments && preg_match( '/<!--.*?-->/',
$comment_or_stuff ) ) ) {
$comments_and_stuff[$i] = '';
}
} else { // stuff between comments
$tags_and_text = preg_split(
"/(<(?:[^>\"']++|\"[^\"]*+(?:\"|$)|'[^']*+(?:'|$))*(?:>|$))/",
$comment_or_stuff, -1, PREG_SPLIT_DELIM_CAPTURE );
foreach ( $tags_and_text as $j => $tag_or_text ) {
$is_broken = false;
$is_allowable = true;
$result = $tag_or_text;
if ( $j % 2 ) { // tag
if ( preg_match(
"%^(</?)([a-z][a-z0-9_]*)\\b(?:[^>\"'/]++|/+?|\"[^\"]*\"|'[^']*')*?(/?>)%i",
$tag_or_text, $matches ) ) {
$tag = strtolower( $matches[2] );
if ( in_array( $tag, $allowable_tags ) ) {
if ( $strip_attrs ) {
$opening = $matches[1];
$closing = ( $opening === '</' ) ? '>' : $closing;
$result = $opening . $tag . $closing;
}
} else {
$is_allowable = false;
$result = '';
}
} else {
$is_broken = true;
$result = '';
}
} else { // text
$tag = false;
}
if ( !$is_broken && isset( $callback ) ) {
// allow result modification
call_user_func_array( $callback, array( &$result, $tag_or_text, $tag, $is_allowable )
);
}
$tags_and_text[$j] = $result;
}
$comments_and_stuff[$i] = implode( '', $tags_and_text );
}
}
$str = implode( '', $comments_and_stuff );
return $str;
}
?>
Callback arguments:
* &$result: contains text to be placed insted of original piece (e.g. empty string for forbidden
tags), it can be changed;
* $tag_or_text: original piece of text or a tag (see below);
* $tag: false for text between tags, lowercase tag name for tags;
* $is_allowable: boolean telling if a tag isn't allowed (to avoid double checking), always true
for text between tags
Callback function isn't called for comments and broken tags.
Caution: the function doesn't fully validate tags (the more so HTML itself), it just force
strips those obviously broken (in addition to stripping forbidden tags). If you want to get valid
tags then use strip_attrs option, though it doesn't guarantee tags are balanced or used in the
appropriate context. For complex logic consider using DOM parser.
----
Server IP: 72.52.91.14
Probable Submitter: 217.74.47.6
----
Manual Page -- http://php.net/manual/en/function.strip-tags.php
Edit -- https://master.php.net/note/edit/118485
Del: integrated -- https://master.php.net/note/delete/118485/integrated
Del: useless -- https://master.php.net/note/delete/118485/useless
Del: bad code -- https://master.php.net/note/delete/118485/bad+code
Del: spam -- https://master.php.net/note/delete/118485/spam
Del: non-english -- https://master.php.net/note/delete/118485/non-english
Del: in docs -- https://master.php.net/note/delete/118485/in+docs
Del: other reasons-- https://master.php.net/note/delete/118485
Reject -- https://master.php.net/note/reject/118485
Search -- https://master.php.net/manage/user-notes.php