在 Yii 2 下,实现 html 富文本的标红,仅替换纯文本,避免替换 html 标签
1、将 html 富文本中的关键词(习近平)加上<em class=”key-word”>习近平</em>,如图1
2、关键词(2017)加上<em class=”key-word”>2017</em>,由于 2017 本身是 src 属性的值,最终导致 html 结构被破坏,页面错乱,如图2
3、查看源代码,src 属性的值被标红,如图3
原始代码:
1 | < img border = "0" style = "max-width:100%;" zcmsimagerela = "125644" src = "http://jnweb.sobeycloud.com/jntxqc//upload/Image/mrtp/bz/2017/08/14/1_e1ac78b7775a43e984a8842d57e703a3.jpg?1502693004515" alt = "timg (2)" /> |
被标红处理后的代码:
1 | < img border = "0" style = "max-width:100%;" zcmsimagerela = "125644" src = "http://jnweb.sobeycloud.com/jntxqc//upload/Image/mrtp/bz/<em class=" key-word">2017</ em >/08/14/1_e1ac78b7775a43e984a8842d57e703a3.jpg?1502693004515" alt="timg (2)"/> |
4、基于:garyjl/yii2-simple_html_dom,参考网址,http://www.shuijingwanwq.com/2018/03/20/2435/ ,安装配置
5、html 富文本内容如下:
1 | < div >第1层节点1< p >第2层节点1,2017,习近平< img border = "0" src = "http://jnweb.sobeycloud.com/jntxqc//upload/Image/mrtp/bz/2017/08/14/1_e1ac78b7775a43e984a8842d57e703a3.jpg?1502693004515" /></ p >< p >第2层节点2</ p >< p >第2层节点3,习近平< span >第3层节点1,2017</ span ></ p >第1层节点2</ div > |
6、编辑 \common\logics\ContentAudit.php,代码如下:如图4
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | <?php namespace common\logics; use Yii; use yii\helpers\Json; use garyjl\simplehtmldom\SimpleHtmlDom; /** * This is the model class for table "{{%content_audit}}". * */ class ContentAudit extends \common\models\ContentAudit { /** * 标注关键词(<em class="key-word"></em>) * @param string $text * @param string $hitContent * * @return string */ public function labelKeyWord( $text , $hitContent ) { foreach ( $hitContent as $hitContentvalue ) { $search [] = $hitContentvalue [ 'word' ]; } $searchUnique = array_unique ( $search ); foreach ( $searchUnique as $searchUniqueValue ) { $replace [] = "<em class='key-word'>" . $searchUniqueValue . "</em>" ; } $replaceText = str_replace ( $searchUnique , $replace , $text ); return $replaceText ; } /** * 获取 HTML DOM 解析的纯文本 * @param string $innerText 内部HTML文本 * * @return array $plainText 纯文本 */ public function getPlainText( $innerText ) { $plainText = []; $html = SimpleHtmlDom::str_get_html( $innerText ); $texts = $html ->find( 'text' ); foreach ( $texts as $text ) { $plainText [] = $text ->plaintext; } return $plainText ; } /** * 标注关键词(设置 HTML DOM 解析的内部HTML文本) * @param string $innerText 内部HTML文本 * @param string $plainText 纯文本 * @param string $hitContent 触发敏感词 * * @return string $replaceInnerText 内部HTML文本 */ public function setInnerText( $innerText , $plainText , $hitContent ) { //标注关键词(<em class="key-word"></em) $labelContent = $this ->labelKeyWord( $plainText , $hitContent ); $labelContent = Json::decode( $labelContent , true); $html = SimpleHtmlDom::str_get_html( $innerText ); foreach ( $labelContent as $key => $text ) { $html ->find( 'text' , $key )->innertext = $labelContent [ $key ]; } // 将内部 DOM 树转储回字符串 $replaceInnerText = $html ->save(); return $replaceInnerText ; } } |
7、编辑 \api\models\ContentAudit.php,代码如下:
1 2 3 4 5 | //获取 HTML DOM 解析的纯文本 $plainText = $this ->getPlainText( $this ->content); print_r( $plainText ); exit ; $textScanContent = Json::encode( $plainText ); |
8、打印 获取 HTML DOM 解析的纯文本,结果如下:如图5
1 2 3 4 5 6 7 8 9 | Array ( [0] => 第1层节点1 [1] => 第2层节点1,2017,习近平 [2] => 第2层节点2 [3] => 第2层节点3,习近平 [4] => 第3层节点1,2017 [5] => 第1层节点2 ) |
9、编辑 \api\models\ContentAudit.php,代码如下:
1 2 3 4 5 | print_r( $textScan ); exit ; //标注关键词(设置 HTML DOM 解析的内部HTML文本) $labelContent = $this ->setInnerText( $this ->content, $textScan [ 'text' ], $textScan [ 'hit_content' ]); $this ->content = $labelContent ; |
10、敏感词过滤是否触发:是,打印触感词触发服务响应的结果,如图6
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | Array ( [hit] => 1 [text] => ["第1层节点1","第2层节点1,2017,习近平","第2层节点2","第2层节点3,习近平","第3层节点1,2017","第1层节点2"] [text_len] => 73 [hit_content] => Array ( [0] => Array ( [word] => 2017 [start] => 18 [end] => 21 [dic_name] => 王强开发专用,允许删除 [id] => 14046 ) [1] => Array ( [word] => 习近平 [start] => 23 [end] => 25 [dic_name] => 王强开发专用,允许删除 [id] => 14048 ) [2] => Array ( [word] => 习近平 [start] => 45 [end] => 47 [dic_name] => 王强开发专用,允许删除 [id] => 14048 ) [3] => Array ( [word] => 2017 [start] => 58 [end] => 61 [dic_name] => 王强开发专用,允许删除 [id] => 14046 ) ) ) |
11、编辑 \api\models\ContentAudit.php,打印 $labelContent,代码如下:
1 2 3 4 5 | //标注关键词(设置 HTML DOM 解析的内部HTML文本) $labelContent = $this ->setInnerText( $this ->content, $textScan [ 'text' ], $textScan [ 'hit_content' ]); print_r( $labelContent ); exit ; $this ->content = $labelContent ; |
12、打印 标注关键词(设置 HTML DOM 解析的内部HTML文本)结果,符合预期,仅替换了纯文本中的关键词,如图7
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | < div >第1层节点1 < p >第2层节点1, < em class = 'key-word' >2017</ em >, < em class = 'key-word' >习近平</ em > < img border = "0" src = "http://jnweb.sobeycloud.com/jntxqc//upload/Image/mrtp/bz/2017/08/14/1_e1ac78b7775a43e984a8842d57e703a3.jpg?1502693004515" /> </ p > < p >第2层节点2</ p > < p >第2层节点3, < em class = 'key-word' >习近平</ em > < span >第3层节点1, < em class = 'key-word' >2017</ em > </ span > </ p >第1层节点2 </ div > |
13、测试 html 富文本,其长度为包含中文 10000 字以上,本地环境响应时间在 1000 ms 以内,可以接受,生产环境可以优化,如图8
近期评论