空间买下来已近很久了,一直没有时间来倒腾,这两天抽空来倒腾这个个人博客,从前端到后端,统统设计再实现一遍-_-!工作量确实还是不小的!
前端那点儿东西,实现起来倒是没有什么障碍,就是日常工作中用到的Smarty3+HTML+Javascript+CSS。
始终不是纯搞后端的,这个得承认,写了一篇文章,入库之前,需要先生成摘要,于是,这个摘要该怎么生成?算法怎么写?
一开始图省事儿,就网上随便找了一段PHP版本的摘要自动生成代码,贴过来以后发现各种BUG,生成出来的摘要简直没法用。
没放弃,继续又找了好几个,效果都非常差,实在忍不住了!!!
分析一下,摘要的生成,重点就是:
1、不能简单的进行strip_tags处理,这样的摘要显示出来无格式,阅读体验很差
2、不能简单的进行substring处理,这样会造成一些标签不能正确闭合,影响页面布局
综合这两点来考虑,其实就没那么复杂了,只需要对富文本源码进行一次HTML词法分析,然后对分析结果进行逐一处理,最后根据具体的长度限制,将结果拼接起来,将未闭合的标签都闭合掉,就可以了。
东西,还是用自家的习惯。咱银总搞的FCP功能很强大,Fl就能够实现这个词法分析的功能,要生成摘要,只需要稍加处理。
改造后的Fl,生成摘要的核心算法,代码如下:
/** * 生成摘要 * @param string $content='' 富文本内容源码 * @param integer $length=3000 摘要字数限制 * @return [type] */ public function generateDigest($content='',$length=3000) { // 实例化Fl $flInstance = self::getInstance(); // HTML词法分析 $analyticResult = $flInstance->analytic_html($content); $result = ''; $htmlTagStack = array(); // 遍历词法分析的结果 foreach ($analyticResult as $key => $item) { // 分析单个标签 $tagAttr = $flInstance->analytic_html($item[0],2); // 开始标签,如:<p>、<div id="xx"> if($item[1] == FL::HTML_TAG_START) { // 将不能自动闭合的标签压栈 if(!$flInstance->analytic_html($tagAttr[1],4)) { $htmlTagStack[] = $tagAttr[1]; } } // 结束标签 elseif($item[1] == FL::HTML_TAG_END) { // 当前结束标签和栈顶的标签相同,则出栈该标签 if($tagAttr[1] == $htmlTagStack[count($htmlTagStack) - 1]) { array_pop($htmlTagStack); } } // 拼接摘要 $result .= $item[0]; // 字数控制 if(strlen($result) >= $length) { break; } } // 将没有闭合的标签,都闭合起来 for ($i=count($htmlTagStack) - 1; $i >= 0 ; $i--) { $result .= ('</' . $htmlTagStack[$i] . '>'); } // 生成最终摘要 return $result; }