在 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
原始代码:
<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)"/>
被标红处理后的代码:
<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 富文本内容如下:
<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
<?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,代码如下:
//获取 HTML DOM 解析的纯文本 $plainText = $this->getPlainText($this->content); print_r($plainText); exit; $textScanContent = Json::encode($plainText);
8、打印 获取 HTML DOM 解析的纯文本,结果如下:如图5
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,代码如下:
print_r($textScan); exit; //标注关键词(设置 HTML DOM 解析的内部HTML文本) $labelContent = $this->setInnerText($this->content, $textScan['text'], $textScan['hit_content']); $this->content = $labelContent;
10、敏感词过滤是否触发:是,打印触感词触发服务响应的结果,如图6
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,代码如下:
//标注关键词(设置 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
<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
近期评论