文章截断使用主要是在列表页面时我没有写描述这样只能在文章中截取字符串了,但使用php 自带函数会导致div未结束,从而页面混乱了,那么要如何解决此问题呢?
博主写好一篇文章,博客后台一般会在搜索页面或者列表页面给出文章标题和截断了的的文章部分作为进一步阅读的入口。
Function: mb_substr( $str, $start, $length, $encoding )
$str,需要截断的字符串
$start,截断开始处
$length,长度(注意,这个跟mb_strimwidth不同,1就代表一个中文字符)
$encoding,编码,我设为 utf-8
例,截断文章标题,控制在15个文字,代码如下:
<?php echo mb_substr('www.phpfensi.com原创', 0, 15,"utf-8"); ?>
这样对于纯文本没问题,但是我的是中间有html标签的于是问题来了,怎样截断一篇文章,注意,这篇文章不仅仅是普通的字符串文本,而是包含了各种格式化标签和样式内容的文本,如果处理不当,这些闭合标签无法正常关闭,从而破坏整个文档流。
如果单纯是纯文本,下面这个函数差不多是够用的,代码如下:
- <?php
-
-
-
-
-
-
-
-
-
-
- function substr_ext($str, $start=0, $length, $charset="utf-8", $suffix="")
- {
- if(function_exists("mb_substr")){
- return mb_substr($str, $start, $length, $charset).$suffix;
- }
- elseif(function_exists('iconv_substr')){
- return iconv_substr($str,$start,$length,$charset).$suffix;
- }
- $re['utf-8'] = "/[x01-x7f]|[xc2-xdf][x80-xbf]|[xe0-xef][x80-xbf]{2}|[xf0-xff][x80-xbf]{3}/";
- $re['gb2312'] = "/[x01-x7f]|[xb0-xf7][xa0-xfe]/";
- $re['gbk'] = "/[x01-x7f]|[x81-xfe][x40-xfe]/";
- $re['big5'] = "/[x01-x7f]|[x81-xfe]([x40-x7e]|xa1-xfe])/";
- preg_match_all($re[$charset], $str, $match);
- $slice = join("",array_slice($match[0], $start, $length));
- return $slice.$suffix;
- }
但是,如果需要截断是网页中的某部分格式化文本,上面的函数就不够用了,它不具备处理格式化标签的能力。
这时,需要一个新函数,它应该是以上函数的升级加强版,它必须有能力正确的处理标签,下面找到一个
strip_tags() 函数剥去 HTML、XML 以及 PHP 的标签。
例子1,代码如下:
- <?php
- echo strip_tags("Hello <b>world!</b>");
- ?>
输出:Hello world!
这样就好做了我们只要在上面基础上如下操作,代码如下:
- <?php
- $a = strip_tags("Hello <b>world!</b>");
- substr_ext( $a,10) ;
-
- ?>
接着google 发现cns写了一个支持html截取字符串的函数,代码如下:
-
-
-
-
-
-
-
-
- function strpos_int($text, $key, $int)
- {
- $keylen = strlen($key);
- global $textlen;
- if (!$textlen)
- $textlen = strlen($text);
- static $textpos = 0;
- $pos = strpos($text, $key);
- $int--;
- if ($pos)
- {
- if ($int == 0)
- $textpos+=$pos;
- else
- $textpos+=$pos + $keylen;
- }
- else
- {
- $int = 0;
- $textpos = $textlen;
- }
- if ($int > 0)
- {
- strpos_int(substr($text, $pos + $keylen), $key, $int);
- }
- return $textpos;
- }
-
-
-
-
-
-
-
-
-
- function cuthtml($string, $length, $dot = ' ...', $append = "")
- {
- $str = strip_tags($string);
- $new_str = iconv_substr($str, 0, $length, 'utf-8');
- $last = iconv_substr($new_str, -1, 1, 'utf-8');
- $sc = substr_count($new_str, $last);
- $position = strpos_int($string, $last, $sc);
- if (function_exists('tidy_parse_string'))
- {
- $options = array("show-body-only" => true);
- return tidy_parse_string(mb_substr($string, 0, $position) . $dot . $append, $options, 'UTF8');
- } else
- {
- if (strlen($string) <= $position)
- {
- return $string;
- }
- $pre = chr(1);
- $end = chr(1);
- $string = str_replace(array('&', '"', '<', '>'), array($pre . '&' . $end, $pre . '"' . $end, $pre . '<' . $end, $pre . '>' . $end), $string);
- $strcut = '';
- $n = $tn = $noc = 0;
- while ($n < strlen($string))
- {
- $t = ord($string[$n]);
- if ($t == 9 || $t == 10 || (32 <= $t && $t <= 126))
- {
- $tn = 1;
- $n++;
- $noc++;
- } elseif (194 <= $t && $t <= 223)
- {
- $tn = 2;
- $n += 2;
- $noc += 2;
- } elseif (224 <= $t && $t <= 239)
- {
- $tn = 3;
- $n += 3;
- $noc += 2;
- } elseif (240 <= $t && $t <= 247)
- {
- $tn = 4;
- $n += 4;
- $noc += 2;
- } elseif (248 <= $t && $t <= 251)
- {
- $tn = 5;
- $n += 5;
- $noc += 2;
- } elseif ($t == 252 || $t == 253)
- {
- $tn = 6;
- $n += 6;
- $noc += 2;
- } else
- {
- $n++;
- }
- if ($noc >= $position)
- {
- break;
- }
- }
- if ($noc > $position)
- {
- $n -= $tn;
- }
- $strcut = substr($string, 0, $n);
- $strcut = str_replace(array($pre . '&' . $end, $pre . '"' . $end, $pre . '<' . $end, $pre . '>' . $end), array('&', '"', '<', '>'), $strcut);
- $pos = strrpos($strcut, chr(1));
- if ($pos !== false)
- {
- $strcut = substr($strcut, 0, $pos);
- }
- return $strcut . $dot . $append;
- }
- }