详谈如何实现PHP HTML截取代码
创始人
2024-06-13 11:20:29
0次

我们今天将为大家带来的是关于PHP HTML截取代码的主要实现方式,希望初学者能通过本文介绍的内容对这方面有一个深刻的认识。

#t#需求:将一段文字截取一定的物理长度显示,注意,要截取的不是字符串的字节数,UFT-8 的编码中文字符是3个字节或者4个字节的,而显示的时候中文会占两个字符的长度,英文字符只占一个,全角的时候又有不同。

而且给的数据是HTML代码串,比如这样:

  1. < div class=”aaa”>
  2. < a href=”/aaa.php?id=1″>
  3. 张三
  4. < /a> 
  5. 评论了 
  6. < a href=”/aaa.php?id=444″>
  7. 李四
  8. < /a> 
  9. 分享的 
  10. < a href=”bbb.html”>
  11. 一篇文章文章一长串的东西
  12. < /a>
  13. < /div> 

PHP HTML截取代码的时候是要截取 div 标签内部的东西,而且要保留HTML标签,只是对其中的文字做处理。比如我可能只是截取到“李四”的“李”字,但是如果就这样放到前端的话,“李四”前面的 a 标签是没有闭合的,所以截取之后要保证HTML的语法正确。
这个问题确实不太好搞,让我郁闷了两天。请注意,这只是一个字符串,只不过内容是HTML代码,是没有什么DOM的。如果是在前端处理就好办了,直接DOM获取,然后对里面的节点进行处理,***把innerHTML 之类的东西输出就搞定了。现在可不行了,得换个思路。同事的思路是这样的:

遍历字符串的每一个字符。设置一个标记,碰到标签开始的标记< 就置为1,接下来的字符都不记数,然后碰到>之后再开始计数。对标签内部的字符串处理的时候,还要先判断当前字符的编码是不是可能是中文,一般来说PHP中 UTF-8 编码的中文字符的长度都是3,所以如果碰到是中文字符编码,就要跳过两个不记数……说到这里我自己头已经开始大了。个人认为这种方法很不爽,首先这种精致的逻辑不太容易控制,而且 UFT-8 编码下中文产生的长度有可能是3个或4个 所以代码的严密性值得怀疑。

我个人的思路是,用 Tidy 来搞(具体用法请看PHP手册吧)。昨天研究了一下那个 Tidy ,发现这个东西还是挺好用的。首先,把这个字符串转换成 Tidy 对象,这样:

  1. $tidy = tidy_parse_string
    ($str, array(), ‘utf8′);   
  2. // ***一个是设置编码的,注意,
    这里是utf8 ,不是utf-8,没有中间那个连线。 

然后获取$tidy中的 body(因为转换之后$tidy会自动加上等标签):
$body = tidy_get_body($tidy);
这个时候你可以用 var_dump 看一些 $body 的结构,会发现它把每个标签都变成了一个对应的对象,里面有相应的属性。举例来说,比如 sdf ,这么一条语句对应的一些属性有:

name=>”a”
value => “sdf”
child=> array{[0]=>一个文本节点对象,value是 sdf}
attribute=array{”href”=>”#”}
…..其他属性

可以看到,我们其实是可以单独去处理 a 标签对应节点下面的文字节点的值的,那样PHP HTML截取代码就不会破坏任何HTML完整性。原来我以为改变 a 标签中文字节点的值之后, a 标签的value也会跟着改变,那样我直接返回a标签对应节点的value就OK了,没想到不是那个样子,哎,所以处理过其中的文字之后还是要自己拼出新的HTML。
知道了Tidy对象的结构之后,一切就好办了,只要遍历所有的节点,对于本需求来说,就是找到那个 div 标签,然后开始处理里面的节点。代码如下:

  1. if(mb_strwidth($subchild->value, 
    ‘utf-8′) >= $len)   
  2. {   
  3. $subchild->value = mb_strimwidth
    ($subchild->value, 0, $len, ‘…', ‘utf-8′);   
  4. $trimed_str .= $subchild->value;   
  5. break;   
  6. }   
  7. else   
  8. {   
  9. $trimed_str .= $subchild->value;   
  10. $len = $len - mb_strwidth($subchild->
    value, ‘utf-8′);   
  11. }  


里面的$subchild 就是一个子节点。注意,这里使用了 mb_strwidth 来获取字符串长度。严重推荐一下这个 mb_strwidth,很好用,它会把中文当作两个字符长度处理,正好符合这里的需求!而且PHP HTML截取代码的时候用到了 mb_strimwidth,这个函数也会把中文当作两个字符长度处理,mb_ 开头的函数真是好用啊。

具体的PHP HTML截取代码代码我就不写出来了,因为是针对一个需求写的,没做成通用的形式。哪天我有时间做成通用的再发布一下。
另外,可惜FireFox不支持 text-overflow 属性,不然也不用后台那么辛苦地去截断了。如果大家有更好的方法,欢迎提出!不胜感激。

相关内容

热门资讯

PHP新手之PHP入门 PHP是一种易于学习和使用的服务器端脚本语言。只需要很少的编程知识你就能使用PHP建立一个真正交互的...
网络中立的未来 网络中立性是什... 《牛津词典》中对“网络中立”的解释是“电信运营商应秉持的一种原则,即不考虑来源地提供所有内容和应用的...
各种千兆交换机的数据接口类型详... 千兆交换机有很多值得学习的地方,这里我们主要介绍各种千兆交换机的数据接口类型,作为局域网的主要连接设...
粉嫩如何诠释霸道 东芝M805... “霸道粉”是个什么玩意东芝M805拿过来的时候,笔者扑哧笑了,不是笑这款笔记本,而是笑这款产品的颜色...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
什么是大数据安全 什么是大数据... 在《为什么需要大数据安全分析》一文中,我们已经阐述了一个重要观点,即:安全要素信息呈现出大数据的特征...
只需三步,让你掌握阿尔法路由器... 请参照以下阿尔法路由器设置方法,通过浏览器进入及设置宽带路由器。经过这三个步骤的设置,基本上能够熟悉...
如何更省钱? 近期特价热门硒鼓... 如今激光打印设备已经成为商务或企业的绝对主力办公设备,但采购者往往忽视了激光打印设备所用的耗材,相对...
全面诠释网络负载均衡 负载均衡的出现大大缓解了服务器的压力,更是有效的利用了资源,提高了效率。那么我们现在来说一下网络负载...
如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...