Home >Backend Development >PHP Tutorial >一个好用的UBB类!_PHP

一个好用的UBB类!_PHP

WBOY
WBOYOriginal
2016-06-01 12:28:381082browse

/*
如有转载,请注明作者

原作者: 何志强
改进:   SonyMusic[sonymusic@163.net]
文件:   ubb.php
备注:   说是改进,其实核心函数parse()已经完全重写了,而且思路也是不一样的。
        不过仍是受何志强的例子的启发,而且测试的例子还有URLCHECK等几个函数也是沿用的何志强的程序,谢谢何志强。
        目前还没有颜色的功能,但我会加入的。
        如果在程序上有什么BUG或不便的地方,请给我MAIL。
        谢谢!
改进功能:
    对字符串进行UBB编码,该类目前只支持下列几个简单且实用的编码:
    1. URL裢接
       http://phpuser.com/
       http://头可以不需要
       如phpuser.com也是可以的。
    2. Email裢接
       sonymusic@163.net
    3. 图片裢接
       
       同URL链接一样,前面的http也可以不要。
    4. 文字方面
       粗体字
       斜体字
       加下划线
       

1号标题字

...
6号标题字

       
       
       [tt][/tt]
       [s][/s]
       
       [em][/em]
       [strong][/strong]
       [code][/code]
       [samp][/samp]
       [kbd][/kbd]
       [var][/var]
       [dfn][/dfn]
       [cite][/cite]
       
       
       
    注意以下几点:
    1. url,email,img等标签是不分大小写的.
    2. 在标签中不允许有TAB键出现,但空格允许。
    3. 该类要调用htmlencode,htmlencode4textarea,emailcheck函数和urlcheck类.
    4. 修改后支持嵌套,但url,email,img这三个标签不是允许嵌套的。
技术资料:
    Ultimate Bulletin Board
        http://www.ultimatebb.com/
    What is UBB Code
        http://www.scriptkeeper.com/ubb/ubbcode.html
*/

include("urlcheck.php");
include("otherfunc.php"); //这两个文件的内容,附在最后。

//ubbcode类
class ubbcode{
    var $call_time=0;
   //可处理标签及处理函数对应表
   var $tags = array(  //小写的标签 => 对应的处理函数
                       'url' => '$this->url',
                       'email' => '$this->email',
                       'img' => '$this->img',
                       'b' => '$this->simple',
                       'i' => '$this->simple',
                       'u' => '$this->simple',
                       'tt' => '$this->simple',
                       's' => '$this->simple',
                       'strike' => '$this->simple',
                       'h1' => '$this->simple',
                       'h2' => '$this->simple',
                       'h3' => '$this->simple',
                       'h4' => '$this->simple',
                       'h5' => '$this->simple',
                       'h6' => '$this->simple',
                       'sup' => '$this->simple',
                       'sub' => '$this->simple',
                       'em' => '$this->simple',
                       'strong' => '$this->simple',
                       'code' => '$this->simple',
                       'samp' => '$this->simple',
                       'kbd' => '$this->simple',
                       'var' => '$this->simple',
                       'dfn' => '$this->simple',
                       'cite' => '$this->simple',
                       'small' => '$this->simple',
                       'big' => '$this->simple',
                       'blink' => '$this->simple'
                    );
   //url裢接属性
   var $attr_url;
   //url合法性检查对象
   var $urlcheck;

   function ubbcode($attr_url){
      $this->attr_url = '.$attr_url;
      $this->urlcheck = new urlcheck();
   }

   //对$str进行UBB编码解析
   function parse($str){
           $this->call_time++;
      $parse = '.htmlencode($str);

      $ret = ';
      while(true){
          $eregi_ret=eregi("\[[#]{0,1}[[:alnum:]]{1,7}\]",$parse,$eregi_arr); //查找[xx]
        if(!$eregi_ret){
            $ret .= $parse;
            break;  //如果没有,返回
         }
         $pos = @strpos($parse,$eregi_arr[0]);
         $tag_len=strlen($eregi_arr[0])-2;//标记长度
        $tag_start=substr($eregi_arr[0],1,$tag_len);
        $tag=strtolower($tag_start);
        
         if((($tag=="url") or ($tag=="email") or ($tag=="img")) and ($this->call_time>1)){
             echo $this->call_time."
";
             return $parse;//如果不能是不能嵌套的标记,直接返回
        }
        
         $parse2 = substr($parse,0,$pos);//标记之前
         $parse = substr($parse,$pos+$tag_len+2);//标记之后
         if(!isset($this->tags[$tag])){
             echo "$tag_start
";
            $ret .= $parse2.'['.$tag_start.']';
            continue;//如果是不支持的标记
         }
        
         //查找对对应的结束标记
         $eregi_ret=eregi("\[\/".$tag."\]",$parse,$eregi_arr);
         if(!$eregi_ret){
            $ret .= $parse2.'['.$tag_start.']';
            continue;//如果没有对应该的结束标记
         }
         $pos=strpos($parse,$eregi_arr[0]);
         $value=substr($parse,0,$pos);//这是起止标记之间的内容
         $tag_end=substr($parse,$pos+2,$tag_len);
         $parse=substr($parse,$pos+$tag_len+3);//结束标记之后的内容
         
         if(($tag!="url") and ($tag!="email") and ($tag!="img")){
             $value=$this->parse($value);
        }

         $ret .= $parse2;
         eval('$ret .= '.$this->tags[$tag].'("'.$tag_start.'","'.$tag_end.'","'.$value.'");');
      }
        $this->call_time--;
      return $ret;
   }

   function simple($start,$end,$value){
      return ''.$value.''.$end.'>';
   }

   function url($start,$end,$value){
           $trim_value=trim($value);
        if (strtolower(substr($trim_value,0,7))!="http://")
            $trim_value="http://".$trim_value;
      if($this->urlcheck->check($trim_value)) return 'attr_url.'>'.$value.'';
      else return '['.$start.']'.$value.'[/'.$end.']';
   }

   function email($start,$end,$value){
      if(emailcheck($value)) return ''.$value.'';
      else return '['.$start.']'.$value.'[/'.$end.']';
   }

   function img($start,$end,$value){
           $trim_value=trim($value);
        if ((strtolower(substr($trim_value,0,7))!="http://") or ($this->urlcheck->check($trim_value)))
               return '一个好用的UBB类!_PHP';
      else return '['.$start.']'.$value.'[/'.$end.']';
   }
}

//测试
echo '';
echo '测试';
echo '';
echo '
';
echo '
';
echo '';
echo '
';

if(isset($ubb)){
   $ubbcode = new ubbcode('target="_blank"');
   echo '
'.$ubbcode->parse($ubb);
}

echo '';
echo '';

?>

文件urlcheck.php的内容
//urlcheck.php
class urlcheck{
   var $regex = array(//协议名(注意在这里必须写成小写) => 对应的正则表达式
                      'ftp' => '$this->ftpurl',
                      'file' => '$this->fileurl',
                      'http' => '$this->httpurl',
                      'https' => '$this->httpurl',
                      'gopher' => '$this->gopherurl',
                      'news' => '$this->newsurl',
                      'nntp' => '$this->nntpurl',
                      'telnet' => '$this->telneturl',
                      'wais' => '$this->waisurl'
                     );

   var $lowalpha;
   var $hialpha;
   var $alpha;
   var $digit;
   var $safe;
   var $extra;
   var $national;
   var $punctuation;
   var $reserved;
   var $hex;
   var $escape;
   var $unreserved;
   var $uchar;
   var $xchar;
   var $digits;

   var $urlpath;
   var $password;
   var $user;
   var $port;
   var $hostnumber;
   var $alphadigit;
   var $toplabel;
   var $domainlabel;
   var $hostname;
   var $host;
   var $hostport;
   var $login;

   //ftp
   var $ftptype;
   var $fsegment;
   var $fpath;
   var $ftpurl;

   //file
   var $fileurl;

   //http,https
   var $search;
   var $hsegment;
   var $hpath;
   var $httpurl;

   //gopher
   var $gopher_string;
   var $selector;
   var $gtype;
   var $gopherurl;

   //news
   var $article;
   var $group;
   var $grouppart;
   var $newsurl;

   //nntp
   var $nntpurl;

   //telnet
   var $telneturl;

   //wais
   var $wpath;
   var $wtype;
   var $database;
   var $waisdoc;
   var $waisindex;
   var $waisdatabase;
   var $waisurl;

   function check($url){
      $pos = @strpos($url,':',1);
      if($pos      $prot = substr($url,0,$pos);
      if(!isset($this->regex[$prot])) return false;
      eval('$regex = '.$this->regex[$prot].';');
      return ereg('^'.$regex.'$',$url);
   }

   function urlcheck(){
      $this->lowalpha = '[a-z]';
      $this->hialpha = '[A-Z]';
      $this->alpha = '('.$this->lowalpha.'|'.$this->hialpha.')';
      $this->digit = '[0-9]';
      $this->safe = '[$.+_-]';
      $this->extra = '[*()\'!,]';
      $this->national = '([{}|\^~`]|\\[|\\])';
      $this->punctuation = '[#%"]';
      $this->reserved = '[?;/:@&=]';
      $this->hex = '('.$this->digit.'|[a-fA-F])';
      $this->escape = '(%'.$this->hex.'{2})';
      $this->unreserved = '('.$this->alpha.'|'.$this->digit.'|'.$this->safe.'|'.$this->extra.')';
      $this->uchar = '('.$this->unreserved.'|'.$this->escape.')';
      $this->xchar = '('.$this->unreserved.'|'.$this->reserved.'|'.$this->escape.')';
      $this->digits = '('.$this->digit.'+)';

      $this->urlpath = '('.$this->xchar.'*)';
      $this->password = '(('.$this->uchar.'|[?;&=]'.')*)';
      $this->user = '(('.$this->uchar.'|[?;&=]'.')*)';
      $this->port = $this->digits;
      $this->hostnumber = '('.$this->digits.'.'.$this->digits.'.'.$this->digits.'.'.$this->digits.')';
      $this->alphadigit = '('.$this->alpha.'|'.$this->digit.')';
      $this->toplabel = '('.$this->alpha.'|('.$this->alpha.'('.$this->alphadigit.'|-)*'.$this->alphadigit.'))';
      $this->domainlabel = '('.$this->alphadigit.'|('.$this->alphadigit.'('.$this->alphadigit.'|-)*'.$this->alphadigit.'))';
      $this->hostname = '(('.$this->domainlabel.'\\.)*'.$this->toplabel.')';
      $this->host = '('.$this->hostname.'|'.$this->hostnumber.')';
      $this->hostport = '('.$this->host.'(:'.$this->port.')?)';
      $this->login = '(('.$this->user.'(:'.$this->password.')?@)?'.$this->hostport.')';

      $this->ftptype = '[aidAID]';
      $this->fsegment = '(('.$this->uchar.'|[?:@&=])*)';
      $this->fpath = '('.$this->fsegment.'(/'.$this->fsegment.')*)';
      $this->ftpurl = '([fF][tT][pP]://'.$this->login.'(/'.$this->fpath.'(;[tT][yY][pP][eE]='.$this->ftptype.')?)?)';

      $this->fileurl = '([fF][iI][lL][eE]://('.$this->host.'|[lL][oO][cC][aA][lL][hH][oO][sS][tT])?/'.$this->fpath.')';

      $this->search = '(('.$this->uchar.'|[;:@&=])*)';
      $this->hsegment = '(('.$this->uchar.'|[;:@&=])*)';
      $this->hpath = '('.$this->hsegment.'(/'.$this->hsegment.')*)';
      $this->httpurl = '([hH][tT][tT][pP][sS]?://'.$this->hostport.'(/'.$this->hpath.'([?]'.$this->search.')?)?)';

      $this->gopher_string = '('.$this->xchar.'*)';
      $this->selector = '('.$this->xchar.'*)';
      $this->gtype = $this->xchar;
      $this->gopherurl = '([gG][oO][pP][hH][eE][rR]://'.$this->hostport.'(/('.$this->gtype.'('.$this->selector.'(%09'.$this->search.'(%09'.$this->gopher_string.')?)?)?)?)?)';

      $this->article = '(('.$this->uchar.'|[;/?:&=])+@'.$this->host.')';
      $this->group = '('.$this->alpha.'('.$this->alpha.'|'.$this->digit.'|[-.+_])*)';
      $this->grouppart = '([*]|'.$this->group.'|'.$this->article.')';
      $this->newsurl = '([nN][eE][wW][sS]:'.$this->grouppart.')';

      $this->nntpurl = '([nN][nN][tT][pP]://'.$this->hostport.'/'.$this->group.'(/'.$this->digits.')?)';

      $this->telneturl = '([tT][eE][lL][nN][eE][tT]://'.$this->login.'/?)';

      $this->wpath = '('.$this->uchar.'*)';
      $this->wtype = '('.$this->uchar.'*)';
      $this->database = '('.$this->uchar.'*)';
      $this->waisdoc = '([wW][aA][iI][sS]://'.$this->hostport.'/'.$this->database.'/'.$this->wtype.'/'.$this->wpath.')';
      $this->waisindex = '([wW][aA][iI][sS]://'.$this->hostport.'/'.$this->database.'[?]'.$this->search.')';
      $this->waisdatabase = '([wW][aA][iI][sS]://'.$this->hostport.'/'.$this->database.')';
      $this->waisurl = '('.$this->waisdatabase.'|'.$this->waisindex.'|'.$this->waisdoc.')';
   }
}

?>


文件otherfunc.php的内容
//otherfunc.php
function htmlencode($str){
   $str = (string)$str;

   $ret = ';
   $len = strlen($str);
   $nl = false;
   for($i=0;$i      $chr = $str[$i];
      switch($chr){
         case '            $ret .= '            $nl = false;
            break;
         case '>':
            $ret .= '>';
            $nl = false;
            break;
         case '"':
            $ret .= '"';
            $nl = false;
            break;
         case '&':
            $ret .= '&';
            $nl = false;
            break;
/*
         case ' ':
            $ret .= ' ';
            $nl = false;
            break;
*/        
         case chr(9):
            $ret .= '    ';
            $nl = false;
            break;
         case chr(10):
            if($nl) $nl = false;
            else{
               $ret .= '
';
               $nl = true;
            }
            break;
         case chr(13):
            if($nl) $nl = false;
            else{
               $ret .= '
';
               $nl = true;
            }
            break;
         default:
            $ret .= $chr;
            $nl = false;
            break;
      }
   }

   return $ret;
}


function htmlencode4textarea($str){
   $str = (string)$str;

   $ret = ';
   $len = strlen($str);
   for($i=0;$i      $chr = $str[$i];
      switch($chr){
         case '            $ret .= '            break;
         case '>':
            $ret .= '>';
            break;
         case '"':
            $ret .= '"';
            break;
         case '&':
            $ret .= '&';
            break;
         case ' ':
            $ret .= ' ';
            break;
         case chr(9):
            $ret .= '    ';
            break;
         default:
            $ret .= $chr;
            break;
      }
   }

   return $ret;
}

function emailcheck($email){
   $ret=false;
   if(strstr($email, '@') && strstr($email, '.')){
      if(eregi("^([_a-z0-9]+([\\._a-z0-9-]+)*)@([a-z0-9]{2,}(\\.[a-z0-9-]{2,})*\\.[a-z]{2,3})$", $email)){
         $ret=true;
      }
   }
   return $ret;
}

function str2url($path){
   return eregi_replace("%2f","/",urlencode($path));
}
?>
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn