【目的】
帖子预览:当字数超过一定限制时,将帖子的一部分显示出来,剩下的用  ..显示全文  来代替【背景】
帖子包含中文,英文,富文本编辑器产生的标签,图片(也是标签引入的),并且帖子内容是经过htmlspecialchars()处理的【目前困难】
1.希望帖子的“一部分”显示出来,这个“一部分”希望是看起来体积差不多大的一个量,而不是说字符一边多,因为utf-8中,如果是用一定字符数做限制的话,英文帖子和中文帖子会有明显的体积不同的结果,我希望最后显示出来,比如说,都是5行
2.正确的在utf-8的环境下切分,不把一个中文字符变成两个乱码
3.在含有图片的帖子也能正确切分,而不是把关于图片的那个标签中间某处切分
4.由于引入了富文本编辑器,所以很多内容都是带有标签的,这个在预览的时候貌似很难处理好,我想,干脆预览的时候就不带富文本那些格式好了,可是不知道是否有方法去掉这些标签
5.由于要考虑用户输入的安全性问题,所以我是要用htmlspecialchars()处理用户输入的。可是先加富文本的那些标签,后用htmlspecialchars()的话,那些标签也都被处理了,结果就是显示的时候,那些标签都显示出来了。于是我就先用htmlspecialchars()处理用户输入,后加富文本的标签【实现样例】
知乎网的在没点开问题的时候,那个样子的预览就是我想要做到的——无格式,包含图,差不多四五行【目前想到的解决方案】
存储的时候把内容存为有格式的正文和截好长度的无格式的预览,这样预览就比较简单了,但问题是如何才能得到去除格式的文字(前文:内容都是在先经过htmlspecialchars()后经过富文本编辑器处理),而且这样做会有冗余,不知道有没有好的办法【其他】
富文本编辑器是由textarea生成的,基于html的,基本就是加标签进去【最后】
我水平太水,光描述这个问题就用了好久,各位大大辛苦了,感谢每一个看完了这个帖子的人。。
我想大家应该理解了我的意思吧?希望没有被我绕晕先行谢过各位了!!另外,我的网站: 思想记http://42.121.107.221    昨天才刚刚上线测试,连备案还没有做好,属于我的个人爱好吧,就是写写自己的思想啊这样的一个地方,在页面底部的关于我们有这个网站的定位,恭请各位大大前来指点!

解决方案 »

  1.   

    图片尺寸不同时(比如某个图片只是一个小ICON或LOGO),为避免变形,缩放是有一个标准的吧,不可能一律显示为同样的尺寸。如果把这个因素算进去,情况会更复杂一点。不过,限制条件越多,实际上方法就越集中和清晰。取得图片的尺寸参与显示控制中即可。中文的问题也是可以解决的。
      

  2.   

    初看之下网站的BUG就不少,有时间用用再汇总一下吧。
      

  3.   

    如果你要精确的一个区域的字的话,光是数字数无论如何都是不行的。
    我曾经做过这方面的,方法是建立一个div,把字(一个img标签也看作一个字)一个一个地加进去,如果发现div高度高于某个预设值,就把字删回去。效率比较低,但胜在效果好。
      

  4.   


    //常用的一个函数,把第一张图片输出,内容再substring~
     /**
         * 获取摘要简介信息
         *
         * @param 原内容 $newContent
         * @param 取得长度 $length
         * @return String
         */
        function getBrief($newContent,$length = 100 , $end = '')
        {
            $pattern = "/<img[^>]*src\=('|\")(([^>]*)(jpg|gif|png|bmp|jpeg))\\1/i";   //获取所有图片标签的全部信
            preg_match_all($pattern, $newContent, $matches);        $str_out = "";
            if( sizeof( $matches[2] ))
            {
                $str_out = "<img width = '30' src = '".$matches[2][0]."' onclick = 'resize_pic(this,30,176)'/>";
            }        $content = strip_tags($newContent);        if(self::strlen_utf8($content)>$length)
            {
                $str_out .= self::subStringUtf8( $content,0,$length) . $end;
            }
            else
            {
                $str_out .= $content;
            }
            return $str_out;
        }
      

  5.   

    你都豁然开朗了还不知道?
    看代码明显有个strip_tags啊
      

  6.   

    这里手册上提供了一个代码,转换文本为纯文本的函数,不过你要自己改进,如果你的代码中有ubb代码神马的function html2txt($document){ 
    $search = array('@<script[^>]*?>.*?</script>@si',  // Strip out javascript 
                   '@<[\/\!]*?[^<>]*?>@si',            // Strip out HTML tags 
                   '@<style[^>]*?>.*?</style>@siU',    // Strip style tags properly 
                   '@<![\s\S]*?--[ \t\n\r]*>@'         // Strip multi-line comments including CDATA 
    ); 
    $text = preg_replace($search, '', $document); 
    return $text; 

      

  7.   


    请问,你的subStringUtf8函数是怎么写的?  (>_<)
      

  8.   


    //sorry 忘记了这个~
    function subStringUtf8($str, $start, $lenth)
        {
            $len = strlen($str);
            $r = array ();
            $n = 0;
            $m = 0;
            for ($i = 0; $i < $len; $i++)
            {
                $x = substr($str, $i, 1);
                $a = base_convert(ord($x), 10, 2);
                $a = substr('00000000' . $a, -8);
                if ($n < $start)
                {
                    if (substr($a, 0, 1) == 0)
                    {
                    }
                    elseif (substr($a, 0, 3) == 110)
                    {
                        $i += 1;
                    }
                    elseif (substr($a, 0, 4) == 1110)
                    {
                        $i += 2;
                    }
                    $n++;
                }
                else
                {
                    if (substr($a, 0, 1) == 0)
                    {
                        $r[] = substr($str, $i, 1);
                    }
                    elseif (substr($a, 0, 3) == 110)
                    {
                        $r[] = substr($str, $i, 2);
                        $i += 1;
                    }
                    elseif (substr($a, 0, 4) == 1110)
                    {
                        $r[] = substr($str, $i, 3);
                        $i += 2;
                    }
                    else
                    {
                        $r[] = '';
                    }
                    if (++ $m >= $lenth)
                    {
                        break;
                    }
                }
            }
            return join("", $r);
        }
      

  9.   


    好复杂的代码,没太看懂,给你看看我的对应函数的代码啊?
    这个是我从网上找来的,用着貌似也挺好,不知道和你的代码有什么区别。。function utf8Substr($str, $from, $len)//截取utf8字符串
    {
    return preg_replace('#^(?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+){0,'.$from.'}'.'((?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+){0,'.$len.'}).*#s','$1',$str);
    }另外,你的resize_pic(this,30,176)  是怎么写的?~
      

  10.   


     function strlen_utf8($str) {
            $i = 0;
            $count = 0;
            $len = strlen ($str);
            while ($i < $len) {
                $chr = ord ($str[$i]);
                $count++;
                $i++;
                if($i >= $len) break;
                if($chr & 0x80) {
                    $chr <<= 1;
                    while ($chr & 0x80) {
                        $i++;
                        $chr <<= 1;
                    }
                }
            }
            return $count;
        }
      

  11.   

    再送几个给你。    // ------------------------------------------------------------------------
        /**
         *
         * 去掉html标记。
         * strip the html
         * @param unknown_type $string
         */
        // ------------------------------------------------------------------------
        public static function stripHtml($string){
            $search = array ("'<script[^>]*?>.*?</script>'si", // 去掉 javascript 4B+1ZsmMd
                "'<[/!]*?[^<>]*?>'si",       // 去掉 HTML 标记
                "'([rn])[s]+'",           // 去掉空白字符
                "'&(quot|#34);'i",           // 替换 HTML 实体
                "'&(amp|#38);'i",
                "'&(lt|#60);'i",
                "'&(gt|#62);'i",
                "'&(nbsp|#160);'i",
                "'&(iexcl|#161);'i",
                "'&(cent|#162);'i",
                "'&(pound|#163);'i",
                "'&(copy|#169);'i",
                "'&#(d+);'e");
            $replace = array(
                "",
                "",
                "\1",
                "\"",
                "&",
                "<",
                ">",
                " ",
                chr(161),
                chr(162),
                chr(163),
                chr(169),
                "chr(\1)");
            return preg_replace($search, $replace, $string);
        } public static function highlightCode($str)
        {
            // The highlight string function encodes and highlights
            // brackets so we need them to start raw
            $str = str_replace(array('&lt;', '&gt;'), array('<', '>'), $str);        // Replace any existing PHP tags to temporary ers so they don't accidentally
            // break the string out of PHP, and thus, thwart the highlighting.        $str = str_replace(array('<?', '?>', '<%', '%>', '\\', '</script>'),
                array('phptagopen', 'phptagclose', 'asptagopen', 'asptagclose', 'backslashtmp', 'scriptclose'), $str);        // The highlight_string function requires that the text be surrounded
            // by PHP tags, which we will remove later
            $str = '<?php '.$str.' ?>'; // <?        // All the magic happens here, baby!
            $str = highlight_string($str, TRUE);        // Prior to PHP 5, the highligh function used icky <font> tags
            // so we'll replace them with <span> tags.        if (abs(PHP_VERSION) < 5)
            {
                $str = str_replace(array('<font ', '</font>'), array('<span ', '</span>'), $str);
                $str = preg_replace('#color="(.*?)"#', 'style="color: \\1"', $str);
            }        // Remove our artificially added PHP, and the syntax highlighting that came with it
            $str = preg_replace('/<span style="color: #([A-Z0-9]+)">&lt;\?php(&nbsp;| )/i', '<span style="color: #$1">', $str);
            $str = preg_replace('/(<span style="color: #[A-Z0-9]+">.*?)\?&gt;<\/span>\n<\/span>\n<\/code>/is', "$1</span>\n</span>\n</code>", $str);
            $str = preg_replace('/<span style="color: #[A-Z0-9]+"\><\/span>/i', '', $str);        // Replace our ers back to PHP tags.
            $str = str_replace(array('phptagopen', 'phptagclose', 'asptagopen', 'asptagclose', 'backslashtmp', 'scriptclose'),
                array('&lt;?', '?&gt;', '&lt;%', '%&gt;', '\\', '&lt;/script&gt;'), $str);
            $str = str_replace( "#FF8000" ,"green" , $str);
            $str = str_replace( "#007700" ,"blue" , $str);        return $str;
        }
        /**
         * Phrase Highlighter
         *
         * Highlights a phrase within a text string
         *
         * @access public
         * @param string the text string
         * @param string the phrase you'd like to highlight
         * @param string the openging tag to precede the phrase with
         * @param string the closing tag to end the phrase with
         * @return string
         */
        public static function highlightPhrase($str, $phrase, $tag_open = '<strong>', $tag_close = '</strong>')
        {
            if ($str == '')
            {
                return '';
            }
            if ($phrase != '')
            {
                return preg_replace('/('.preg_quote($phrase, '/').')/i', $tag_open."\\1".$tag_close, $str);
            }        return $str;
        }    public static function highlightSearch($keyword, $str)
        {
            $str = str_replace($keyword , "<font color='red'>$keyword</font>" , $str);
            return $str;
        }function convert64To10($fifty_two) {
            if( is_int($fifty_two)) $fifty_two .= "";
            $base_map = array (
                'Y' => 0,
                'j' => 1,
                'E' => 2,
                'q' => 3,
                'm' => 4,
                'w' => 5,
                'p' => 6,
                'Q' => 7,
                's' => 8,
                'r' => 9,
                'D' => 10,
                'V' => 11,
                'G' => 12,
                'B' => 13,
                'S' => 14,
                'o' => 15,
                'U' => 16,
                'i' => 17,
                'K' => 18,
                'A' => 19,
                'f' => 20,
                'n' => 21,
                'v' => 22,
                'z' => 23,
                'O' => 24,
                'X' => 25,
                'H' => 26,
                'h' => 27,
                'J' => 28,
                'P' => 29,
                'C' => 30,
                'N' => 31,
                'k' => 32,
                'R' => 33,
                't' => 34,
                'L' => 35,
                'a' => 36,
                'Z' => 37,
                'u' => 38,
                'W' => 39,
                'y' => 40,
                'x' => 41,
                'I' => 42,
                'b' => 43,
                'M' => 44,
                'e' => 45,
                'T' => 46,
                'F' => 47,
                'd' => 48,
                'l' => 49,
                'c' => 50,
                'g' => 51,
                '0' => 52,
                '1' => 53,
                '2' => 54,
                '3' => 55,
                '4' => 56,
                '5' => 57,
                '6' => 58,
                '7' => 59,
                '8' => 60,
                '9' => 61,
                '-' => 62,
                '_' => 63
            );
            $result = 0;
            $len = strlen($fifty_two);        for ($n = 0; $n < $len; $n++) {
                $result *= 64;
                $result += $base_map[$fifty_two[$n]];
            }
            return $result;
        }    /**
         * 将十进制转换为64进制.
         *
         * @param unknown_type $dec
         * @return unknown
         */
        public static function convert10To64($dec) {
            $base = 'YjEqmwpQsrDVGBSoUiKAfnvzOXHhJPCNkRtLaZuWyxIbMeTFdlcg0123456789-_';
            $result = '';
            do {
                $result = $base[$dec % 64] . $result;
                $dec = intval($dec / 64);
            } while ($dec != 0);
            return $result;
        }
        public static function showDateString( $data )
        {
            //echo $data;
            $Srctime = strtotime($data );
            $timeToday = strtotime( date("Y-m-d"));
            $timeDiff = $Srctime - $timeToday;  //判断与今天的时间差!
            if( $timeDiff >0 )
            {
                $timeStr = "今天".date("H:i" , $Srctime );
            }        if( $timeDiff <0 && $timeDiff > -365*86400 )
            {
                $timeStr = date("m-d H:i" , $Srctime );
            }        if( $timeDiff < -365 * 86400 )
            {
                $timeStr = date("Y-m-d H:i" , $Srctime );
            }
            return $timeStr;
        }
        /*
         * 显示倒计时.
         */
        public static function showEndDateString( $endTime )
        {
            /*
                PHP制作剩余时间显示
              */
            $end_famate_time = strtotime($endTime); //结束时间转化为时间戳        $now_time = time();        $remain_time = $end_famate_time-$now_time; //剩余的秒数
            if( $remain_time < 0) return "已到期";        $remain_day = floor($remain_time/(60*60*24)); //剩余的天        $remain_hour = floor($remain_time/(60*60))%24; //剩余的小时
            $remain_minute = floor(($remain_time - $remain_hour*60*60)/60)%60; //剩余的分钟数
            $remain_second = ($remain_time - $remain_hour*60*60 - $remain_minute*60)%60; //剩余的秒数
            $string =$remain_day . "天". $remain_hour . "小时" ;
            return  $string;
        }    /**
         * 显示正计时
         * @static
         * @param $endTime
         * @return string
         */
        public static function showStartDateString( $endTime )
        {
            /*
                PHP制作剩余时间显示
              */
            $end_famate_time = strtotime($endTime); //结束时间转化为时间戳        $now_time = time();        $remain_time = $now_time -  $end_famate_time; //剩余的秒数        if( $remain_time < 0) return "故障时间";        $remain_hour = floor($remain_time/(60*60))%24; //剩余的小时        $remain_minute = floor(($remain_time - $remain_hour*60*60)/60)%60; //剩余的分钟数
            $remain_second = ($remain_time - $remain_hour*60*60 - $remain_minute*60)%60; //剩余的秒数
            /*
            $remain_day = floor($remain_time/(60*60*24)); //剩余的天        */
            $string = $remain_hour . "小时" . $remain_minute ."分" .$remain_second."秒" ;
            echo $string;
            return  $string;
        }