contentpage.class.php 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. <?php
  2. /**
  3. * contentpage.class.php 文章内容页分页类
  4. *
  5. * @copyright (C) 2005-2010 PHPCMS
  6. * @license http://www.phpcms.cn/license/
  7. * @lastmodify 2010-8-12
  8. */
  9. class contentpage {
  10. private $additems = array (); //定义需要补全的开头html代码
  11. private $bottonitems = array (); //定义需要补全的结尾HTML代码
  12. private $html_tag = array (); //HTML标记数组
  13. private $surplus; //剩余字符数
  14. public $content; //定义返回的字符
  15. public function __construct() {
  16. //定义HTML数组
  17. $this->html_tag = array ('p', 'div', 'h', 'span', 'strong', 'ul', 'ol', 'li', 'table', 'tr', 'tbody', 'dl', 'dt', 'dd');
  18. $this->html_end_tag = array ('/p', '/div', '/h', '/span', '/strong', '/ul', '/ol', '/li', '/table', '/tr', '/tbody', '/dl', '/dt', '/dd');
  19. $this->content = ''; //临时内容存储器
  20. $this->data = array(); //内容存储
  21. }
  22. /**
  23. * 处理并返回字符串
  24. *
  25. * @param string $content 待处理的字符串
  26. * @param intval $maxwords 每页最大字符数。去除HTML标记后字符数
  27. * @return 处理后的字符串
  28. */
  29. public function get_data($content = '', $maxwords = 10000) {
  30. if (!$content) return '';
  31. $this->data = array();
  32. $this->content = '';
  33. //exit($maxwords);
  34. $this->surplus = $maxwords; //开始时将剩余字符设置为最大
  35. //判断是否存在html标记,不存在直接按字符数分页;如果存在HTML标记,需要补全缺失的HTML标记
  36. if (strpos($content, '<')!==false) {
  37. $content_arr = explode('<', $content); //将字符串按‘<’分割成数组
  38. $this->total = count($content_arr); //计算数组值的个数,便于计算是否执行到字符串的尾部
  39. foreach ($content_arr as $t => $c) {
  40. if ($c) {
  41. $s = strtolower($c); //大小写不区分
  42. //$isadd = 0;
  43. if ((strpos($c, ' ')!==false) && (strpos($c, '>')===false)) {
  44. $min_point = intval(strpos($c, ' '));
  45. } elseif ((strpos($c, ' ')===false) && (strpos($c, '>')!==false)) {
  46. $min_point = intval(strpos($c, '>'));
  47. } elseif ((strpos($c, ' ')!==false) && (strpos($c, '>')!==false)) {
  48. $min_point = min(intval(strpos($c, ' ')), intval(strpos($c, '>')));
  49. }
  50. $find = substr($c, 0, $min_point);
  51. //if ($t>26) echo $s.'{}'.$find.'<br>';
  52. //preg_match('/(.*)([^>|\s])/i', $c, $matches);
  53. if (in_array(strtolower($find), $this->html_tag)) {
  54. $str = '<'.$c;
  55. $this->bottonitems[$t] = '</'.$find.'>'; //属于定义的HTML范围,将结束标记存入补全的结尾数组
  56. if(preg_match('/<'.$find.'(.*)>/i', $str, $match)) {
  57. $this->additems[$t] = $match[0]; //匹配出开始标记,存入补全的开始数组
  58. }
  59. $this->separate_content($str, $maxwords, $match[0], $t); //加入返回字符串中
  60. } elseif (in_array(strtolower($find), $this->html_end_tag)) { //判断是否属于定义的HTML结尾标记
  61. ksort($this->bottonitems);
  62. ksort($this->additems);
  63. if (is_array($this->bottonitems) && !empty($this->bottonitems)) array_pop($this->bottonitems); //当属于是,将开始和结尾的补全数组取消一个
  64. if (is_array($this->additems) && !empty($this->additems)) array_pop($this->additems);
  65. $str = '<'.$c;
  66. $this->separate_content($str, $maxwords, '', $t); //加入返回字符串中
  67. } else {
  68. if($t==0){
  69. $tag = $c;//第一个不可能有<
  70. }else{
  71. $tag = '<'.$c;
  72. }
  73. if ($this->surplus >= 0) {
  74. $this->surplus = $this->surplus-strlen(strip_tags($tag));
  75. if ($this->surplus<0) {
  76. $this->surplus = 0;
  77. }
  78. }
  79. $this->content .= $tag; //不在定义的HTML标记范围,则将其追加到返回字符串中
  80. if (intval($t+1) == $this->total) { //判断是否还有剩余字符
  81. $this->content .= $this->bottonitem();
  82. $this->data[] = $this->content;
  83. }
  84. }
  85. }
  86. }
  87. } else {
  88. $this->content .= $this->separate_text($content, $maxwords); //纯文字时
  89. }
  90. return implode('[page]', $this->data);
  91. }
  92. /**
  93. * 处理纯文本数据
  94. * @param string $str 每条数据
  95. * @param intval $max 每页的最大字符
  96. */
  97. private function separate_text($str = '', $max){
  98. $str = strip_tags($str);
  99. $total = ceil(strlen($str)/$max);
  100. $encoding = 'utf-8';
  101. if(strtolower(CHARSET)=='gbk') $encoding = 'gbk';
  102. if(function_exists("mb_strcut")){
  103. for ( $i=0; $i < $total; $i++ )
  104. {
  105. $this->data[] =mb_strcut($str,$i*$max,$max,$encoding);
  106. }
  107. }
  108. return true;
  109. }
  110. /**
  111. * 处理每条数据
  112. * @param string $str 每条数据
  113. * @param intval $max 每页的最大字符
  114. * @param string $tag HTML标记
  115. * @param intval $t 处理第几个数组,方便判断是否到字符串的末尾
  116. * @param intval $n 处理的次数
  117. * @param intval $total 总共的次数,防止死循环
  118. * @return boolen
  119. */
  120. private function separate_content($str = '', $max, $tag = '', $t = 0, $n = 1, $total = 0) {
  121. $html = $str;
  122. $str = strip_tags($str);
  123. if ($str) $str = @str_replace(array(' '), '', $str);
  124. if ($str) {
  125. if ($n == 1) {
  126. $total = ceil((strlen($str)-$this->surplus)/$max)+1;
  127. }
  128. if ($total<$n) {
  129. return true;
  130. } else {
  131. $n++;
  132. }
  133. if (strlen($str)>$this->surplus) { //当前字符数超过最大分页数时
  134. $remove_str = str_cut($str, $this->surplus, '');
  135. $this->content .= $tag.$remove_str; //连同标记加入返回字符串
  136. $this->content .= $this->bottonitem(); //补全尾部标记
  137. $this->data[] = $this->content; //将临时的内容放入数组中
  138. $this->content = ''; //设置为空
  139. $this->content .= $this->additem(); //补全开始标记
  140. $str = str_replace($remove_str, '', $str); //去除已加入
  141. $this->surplus = $max;
  142. return $this->separate_content($str, $max, '', $t, $n, $total); //判断剩余字符
  143. } elseif (strlen($str)==$this->surplus) { //当前字符刚好等于时(彩票几率)
  144. $this->content .= $html;
  145. $this->content .= $this->bottonitem();
  146. if (intval($t+1) != $this->total) { //判断是否还有剩余字符
  147. $this->data[] = $this->content; //将临时的内容放入数组中
  148. $this->content = ''; //设置为空
  149. $this->content .= $this->additem();
  150. }
  151. $this->surplus = $max;
  152. } else { //当前字符数少于最大分页数
  153. $this->content .= $html;
  154. if (intval($t+1) == $this->total) { //判断是否还有剩余字符
  155. $this->content .= $this->bottonitem();
  156. $this->data[] = $this->content;
  157. }
  158. $this->surplus = $this->surplus-strlen($str);
  159. }
  160. } else {
  161. $this->content .= $html;
  162. if ($this->surplus == 0) {
  163. $this->content .= $this->bottonitem();
  164. if (intval($t+1) != $this->total) { //判断是否还有剩余字符
  165. $this->data[] = $this->content; //将临时的内容放入数组中
  166. $this->content = ''; //设置为空
  167. $this->surplus = $max;
  168. $this->content .= $this->additem();
  169. }
  170. }
  171. if (intval($t+1) == $this->total) { //判断是否还有剩余字符
  172. $this->content .= $this->bottonitem();
  173. $this->data[] = $this->content;
  174. }
  175. }
  176. if ($t==($this->total-1)) {
  177. $pop_arr = array_pop($this->data);
  178. if ($pop = strip_tags($pop_arr)) {
  179. $this->data[] = $pop_arr;
  180. }
  181. }
  182. return true;
  183. }
  184. /**
  185. * 补全开始HTML标记
  186. */
  187. private function additem() {
  188. $content = '';
  189. if (is_array($this->additems) && !empty($this->additems)) {
  190. ksort($this->additems);
  191. foreach ($this->additems as $add) {
  192. $content .= $add;
  193. }
  194. }
  195. return $content;
  196. }
  197. /**
  198. * 补全结尾HTML标记
  199. */
  200. private function bottonitem() {
  201. $content = '';
  202. if (is_array($this->bottonitems) && !empty($this->bottonitems)) {
  203. krsort($this->bottonitems);
  204. foreach ($this->bottonitems as $botton) {
  205. $content .= $botton;
  206. }
  207. }
  208. return $content;
  209. }
  210. }
  211. ?>