我编写了一个函数,用于使用PHP转换HTML代码中的BB代码。这个剧本非常有效,但我遇到了一个大问题。页面加载时间非常慢。整个第一个版本是在阵列中制作的,但加载速度很慢。版本2是使用单独的preg_replace和str_replace制作的,它们需要加载的时间越少,但仍然在加载大文本时会产生问题。
有人可以帮助减少此脚本并加快加载速度吗?
这是我的剧本:
function bb2html($bb2html)
{
/**********************************
* Generator BB code to HTML
* version: 2.5 BETA
* updated: 19.06.2014.
***********************************/
$bb2html = str_replace('[[[[','**$@$**[[', $bb2html);
$bb2html = str_replace(']]]]',']]**@^@**', $bb2html);
$bb2html = str_replace('[[[','**$@$**[', $bb2html);
$bb2html = str_replace(']]]',']**@^@**', $bb2html);
$bb2html = str_replace('[[','**$@$**', $bb2html);
$bb2html = str_replace(']]','**@^@**', $bb2html);
// Lovercase BB
$allow='[c, [sp, [br, [url, [center, [left, [right, [news, [div, [span, [font, [b, [bold, [big, [small, [list, [ul, [li, [tt, [ol, [code, [quote, [block, [cite, [u, [i, [em, [p, [s, [h1, [h2, [h3, [h4, [h5, [h6, [color, [size, [img, [email, [mail, [link, [url';
$allowed=array();
foreach(explode(",", $allow) as $result){$result=trim($result);$allowed[]=$result;}
while ($lowerrcase = strstr($bb2html, '['))
{
$k = (strpos($lowerrcase, ']') > (strpos($lowerrcase, ' ')))?' ':']';
$lowerrcase = substr($lowerrcase, 1, strpos($lowerrcase, $k));
$find=strstr($lowerrcase, '[');
if(in_array('['.strtolower($find), $allowed)) $bb2html = str_replace('['.$lowerrcase, '**%^%**'.strtolower($lowerrcase), $bb2html);
else $bb2html = str_replace('['.$lowerrcase, '**%^%**'.$lowerrcase, $bb2html);
}
$bb2html=str_replace('**%^%**', '[', $bb2html);
// Auto close opened tags
$tags_to_close = array('[*]','[b]','[i]','[u]','[big]','[ul]','[list]','[ol]','[center]','[left]','[right]','[tt]','[s]','[code]',
'[block]','[h1]','[h2]','[h3]','[h4]','[h5]','[h6]','[quote]');
foreach ($tags_to_close as $key => $value)
{
$open = substr_count($bb2html, $value);
$close_tag = '[/'.substr($value, 1);
while (substr_count($bb2html, $close_tag) < $open){$bb2html.= $close_tag;}
}
$check_string = preg_replace("/\[\!--(.+)--\]/i","",$bb2html); // we support comments!
$removers = array('[hr]','[hr2]','[hr3]','[hr4]','[/br]','[/sp]','[/*]','[/c]'); // Remove some tags
$bb2html = str_replace($removers, '', str_replace($removers, '', $check_string));
/*
xss clean-up
clean up against potential xss attacks
adapted from the bitflux xss prevention techniques..
http://blog.bitflux.ch/wiki/XSS_Prevention
*/
$bb2html = implode("",explode("\\",$bb2html));
// fix &entitiy\n; (except those named above)
$bb2html = preg_replace('#(&\#*\w+)[\x00-\x20]+;#us',"$1;",$bb2html);
$bb2html = preg_replace('#(&\#x*)([0-9A-F]+);*#ius',"$1$2;",$bb2html);
$bb2html = html_entity_decode($bb2html, ENT_COMPAT);
//$bb2html = html_entity_decode($bb2html, ENT_COMPAT, "utf-8"); // if your php is capable of this :pref:
// remove "on" and other unnecessary attributes (we specify them all to prevent words like "one" being affected)
$bb2html = preg_replace('#(\[[^\]]+[\x00-\x20\"\'])(onabort|onactivate|onafterprint|onafterupdate|onbeforeactivate|onbeforecopy|onbeforecut|onbeforedeactivate|onbeforeeditfocus|onbeforepaste|onbeforeprint|onbeforeunload|onbeforeupdate|onblur|onbounce|oncellchange|onchange|onclick|oncontextmenu|oncontrolselect|oncopy|oncut|ondataavailable|ondatasetchanged|ondatasetcomplete|ondblclick|ondeactivate|ondrag|ondragend|ondragenter|ondragleave|ondragover|ondragstart|ondrop|onerror|onerrorupdate|onfilterchange|onfinish|onfocus|onfocusin|onfocusout|onhelp|onkeydown|onkeypress|onkeyup|onlayoutcomplete|onload|onlosecapture|onmousedown|onmouseenter|onmouseleave|onmousemove|onmouseout|onmouseover|onmouseup|onmousewheel|onmove|onmoveend|onmovestart|onpaste|onpropertychange|onreadystatechange|onreset|onresize|onresizeend|onresizestart|onrowenter|onrowexit|onrowsdelete|onrowsinserted|onscroll|onselect|onselectionchange|onselectstart|onstart|onstop|onsubmit|onunload|xmlns|datasrc|src|lowsrc|dynsrc)[^\]]*\]#isUu',"$1]", $bb2html);
// remove javascript and vbscript...
$bb2html = preg_replace('#([a-z]*)[\x00-\x20]*=?[\x00-\x20]*([\`\'\"]*)[\\x00-\x20]*j[\x00-\x20]*a[\x00-\x20]*v[\x00-\x20]*a[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iUu', '$1=$2nojavascript...', $bb2html);
$bb2html = preg_replace('#([a-z]*)[\x00-\x20]*=?([\'\"]*)[\x00-\x20]*v[\x00-\x20]*b[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iUu', '$1=$2novbscript...', $bb2html);
// style expression hacks. only works in buggy ie... (fer fuxake! get a browser!)
$bb2html = preg_replace('#(\[[^\]]+)style[\x00-\x20]*=[\x00-\x20]*([\`\'\"]*).*expression[\x00-\x20]*\([^\]]*>#iUs', "$1\]", $bb2html);
$bb2html = preg_replace('#(\[[^\]]+)style[\x00-\x20]*=[\x00-\x20]*([\`\'\"]*).*behaviour[\x00-\x20]*\([^\]]*>#iUs', "$1\]", $bb2html);
$bb2html = preg_replace('#(\[[^\]]+)style[\x00-\x20]*=[\x00-\x20]*([\`\'\"]*).*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:*[^\]]*\]>#iUus',"$1\]", $bb2html);
// remove namespaced elements..
$bb2html = preg_replace('#\[/*\w+:\w[^\]]*\]#is',"", $bb2html);
// the really fun <tags>...
do {
$oldbb2html = $bb2html;
$bb2html = preg_replace('#\[/*(applet|meta|xml|link|style|script|embed|object|iframe|frame|frameset|ilayer|layer|bgsound|base|sourcetext|parsererror)[^[]*\]#is',"",$bb2html);
} while ($oldbb2html != $bb2html); // loop through to catch tricky doubles
// leave no trace..
if (get_magic_quotes_gpc()) $bb2html = addslashes($bb2html);
// Pre-formatted text
$pre = array(); $i = 9999;
while ($pre_str = stristr($bb2html, '[pre]'))
{
$pre_str = substr($pre_str, 0, strpos($pre_str, '[/pre]') + 6);
$bb2html = str_replace($pre_str, "***pre_string***$i", $bb2html);
$encode = str_replace("\r\n", "\n", str_replace(array('**$@$**', '**@^@**'), array('[[', ']]'), $pre_str));
$pre[$i] = htmlentities(str_replace(array('[pre]','[/pre]'),'', $encode ), ENT_NOQUOTES, 'utf-8');
$i++;
}
// Syntax highlighting
$color_code = array(); $i = 0;
while ($color_code_str = stristr($bb2html, '[ccc]'))
{
$color_code_str = substr($color_code_str, 0, strpos($color_code_str, '[/ccc]') + 6);
$bb2html = str_replace($color_code_str, "***ccc_string***$i", $bb2html);
$color_code[$i] = str_replace(array('**$@$**', '**@^@**', "\r\n"), array('[[', ']]', "\n"), $color_code_str);
$i++;
}
// Generic entity encode
$bb2html = htmlentities($bb2html, ENT_NOQUOTES, 'utf-8');
$bb2html = str_replace('>','>', $bb2html);
$bb2html = str_replace('<','<', $bb2html);
$bb2html = str_replace('[c]','©', $bb2html);
$bb2html = str_replace('[sp]',' ', $bb2html);
$bb2html = str_replace("[br]",'<br />', $bb2html);
$bb2html = str_replace("\r\n",'<br />', $bb2html);
$bb2html = str_replace("\n",'<br />', $bb2html);
$bb2html = str_replace('%0D%0A','<br />', $bb2html);
$bb2html = str_replace("<br/>","<br />", $bb2html);
$bb2html = str_replace("<br />","<br>", $bb2html);
// Delete URL protocols, because will be added when convert the code PROTECTED MOD
$bb2html = str_replace('[url=http://','[url=', $bb2html);
$bb2html = str_replace('[url=https://','[url=', $bb2html);
$bb2html = str_replace('[url=ftp://','[url=', $bb2html);
$bb2html = str_replace('[url=news://','[url=', $bb2html);
$bb2html = str_replace('[url]http://','[url]', $bb2html);
$bb2html = str_replace('[url]https://','[url]', $bb2html);
$bb2html = str_replace('[url]ftp://','[url]', $bb2html);
$bb2html = str_replace('[url]news://','[url]', $bb2html);
// other tags
$bb2html = str_replace('[*]','<li>', $bb2html);
$bb2html = str_replace('[/*]','</li>', $bb2html);
// GLOBAL replace closed tags
$bb2html = preg_replace('/\[center\](.*?)\[\/center\]/is','<div align="center">$1</div>', $bb2html);
$bb2html = preg_replace('/\[left\](.*?)\[\/left\]/is','<div align="left">$1</div>', $bb2html);
$bb2html = preg_replace('/\[right\](.*?)\[\/right\]/is','<div align="right">$1</div>', $bb2html);
$bb2html = preg_replace('/\[news\](.*?)\[\/news\]/is','<div class="news" id="news">$1</div>', $bb2html);
$bb2html = preg_replace('/\[div\](.*?)\[\/div\]/is','<div>$1</div>', $bb2html);
$bb2html = preg_replace('/\[span\](.*?)\[\/span\]/is','<span>$1</span>', $bb2html);
$bb2html = preg_replace('/\[font\](.*?)\[\/font\]/is','<font>$1</font>', $bb2html);
$bb2html = preg_replace('/\[font=(.*?)\](.*?)\[\/font\]/is','<font style="font-family:$1">$2</font>', $bb2html);
$bb2html = preg_replace('/\[b\](.*?)\[\/b\]/is','<strong>$1</strong>', $bb2html);
$bb2html = preg_replace('/\[bold\](.*?)\[\/bold\]/is','<strong>$1</strong>', $bb2html);
$bb2html = preg_replace('/\[strong\](.*?)\[\/strong\]/is','<strong>$1</strong>', $bb2html);
$bb2html = preg_replace('/\[big\](.*?)\[\/big\]/is','<big>$1</big>', $bb2html);
$bb2html = preg_replace('/\[small\](.*?)\[\/small\]/is','<small>$1</small>', $bb2html);
$bb2html = preg_replace('/\[list\](.*?)\[\/list\]/is','<ol>$1</ol>', $bb2html);
$bb2html = preg_replace('/\[list=(.*?)\](.*?)\[\/list\]/is','<ol start="$1">$2</ol>', $bb2html);
$bb2html = preg_replace('/\[ul\](.*?)\[\/ul\]/is','<ul>$1</ul>', $bb2html);
$bb2html = preg_replace('/\[li\](.*?)\[\/li\]/is','<li>$1</li>', $bb2html);
$bb2html = preg_replace('/\[tt\](.*?)\[\/tt\]/is','<tt>$1</tt>', $bb2html);
$bb2html = preg_replace('/\[code\](.*?)\[\/code\]/is','<code>$1</code>', $bb2html);
$bb2html = preg_replace('/\[quote\](.*?)\[\/quote\]/is','<blockquote>$1</blockquote>', $bb2html);
$bb2html = preg_replace('/\[block\](.*?)\[\/block\]/is','<blockquote>$1</blockquote>', $bb2html);
$bb2html = preg_replace('/\[cite\](.*?)\[\/cite\]/is','<cite>$1</cite>', $bb2html);
$bb2html = preg_replace('/\[u\](.*?)\[\/u\]/is','<u>$1</u>', $bb2html);
$bb2html = preg_replace('/\[i\](.*?)\[\/i\]/is','<em>$1</em>', $bb2html);
$bb2html = preg_replace('/\[em\](.*?)\[\/em\]/is','<em>$1</em>', $bb2html);
$bb2html = preg_replace('/\[p\](.*?)\[\/p\]/is','<p>$1</p>', $bb2html);
$bb2html = preg_replace('/\[s\](.*?)\[\/s\]/is','<span style="text-decoration:line-through">$1</span>', $bb2html);
$bb2html = preg_replace('/\[h1\](.*?)\[\/h1\]/is','<h1>$1</h1>', $bb2html);
$bb2html = preg_replace('/\[h2\](.*?)\[\/h2\]/is','<h2>$1</h2>', $bb2html);
$bb2html = preg_replace('/\[h3\](.*?)\[\/h3\]/is','<h3>$1</h3>', $bb2html);
$bb2html = preg_replace('/\[h4\](.*?)\[\/h4\]/is','<h4>$1</h4>', $bb2html);
$bb2html = preg_replace('/\[h5\](.*?)\[\/h5\]/is','<h5>$1</h5>', $bb2html);
$bb2html = preg_replace('/\[h6\](.*?)\[\/h6\]/is','<h6>$1</h6>', $bb2html);
$bb2html = preg_replace('/\[color=(.*?)\](.*?)\[\/color\]/is','<font style="color:$1;">$2</font>', $bb2html);
$bb2html = preg_replace('/\[size=(.*?)\](.*?)\[\/size\]/is','<span style="font-size:$1%;">$2</span>', $bb2html);
$bb2html = preg_replace('/\[img\](.*?)\[\/img\]/is','<img src="$1">', $bb2html);
$bb2html = preg_replace('/\[img=(.*?)\](.*?)\[\/img\]/is','<img src="$1" title="$2" alt="$2">', $bb2html);
$bb2html = preg_replace('/\[email\]([_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3}))\[\/email\]/is','<a href="mailto:$1">$1</a>', $bb2html);
$bb2html = preg_replace('/\[mail\]([_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3}))\[\/mail\]/is','<a href="mailto:$1">$1</a>', $bb2html);
$bb2html = preg_replace('/\[url\=(.*?)\](.*?)\[\/url\]/is','<a target="_blank" href="http://$1">$2</a>', $bb2html);
$bb2html = preg_replace('/\[url\](.*?)\[\/url\]/is','<a target="_blank" href="http://$1">$1</a>', $bb2html);
$bb2html = preg_replace('/\[link\=(.*?)\](.*?)\[\/link\]/is','<a target="_blank" href="http://$1">$2</a>', $bb2html);
$bb2html = preg_replace('/\[link\](.*?)\[\/link\]/is','<a target="_blank" href="http://$1">$1</a>', $bb2html);
if (get_magic_quotes_gpc()) $bb2html = implode("",explode("\\",$bb2html));
// CLEAR TRASH
$bb2html = preg_replace('|[[\/\!]*?[^\[\]]*?]|si', '', $bb2html);
// for URL's, and Infini Tags..
$bb2html = str_replace('/ >','/>', $bb2html);
$bb2html = str_replace('-- >','-->', $bb2html);
// XML trash
$replace_tags=array(
"/\<xml(.+?)\>(.+?)\<\/xml\>/is",
"/\<w:(.+?)\>(.+?)\<\/w:(.+?)\>/is",
"/\<o:(.+?)\>/is",
"/<\?(.*)\? ?>/is",
"/\<\!--(.+)--\>/i",
"/\<\!--(.+)\>/i",
);
$bb2html = preg_replace($replace_tags, "", $bb2html);
$replace_tags=false;
// make some injection for visual code
$bb2html = str_replace('<br>',"<br>", $bb2html);
$bb2html = str_replace('<ol>',"<ol>\r\n", $bb2html);
$bb2html = str_replace('</ol>',"\r\n</ol>", $bb2html);
$bb2html = str_replace('<ul>',"<ul>\r\n", $bb2html);
$bb2html = str_replace('</ul>',"\r\n</ul>", $bb2html);
$bb2html = str_replace('<tt>',"<tt>\r\n", $bb2html);
$bb2html = str_replace('</tt>',"\r\n</tt>", $bb2html);
// re-insert the preformatted text blocks..
$cp = count($pre) + 9998;
for ($i=9999;$i <= $cp;$i++) {$bb2html = str_replace("***pre_string***$i", '<pre>'.$pre[$i].'</pre>', $bb2html);}
// re-insert the colored code, we fix-up the output, too, make it xhtml strict.
$cp = count($color_code) - 1;
for ($i=0 ; $i <= $cp ; $i++)
{
$tmp_str = substr($color_code[$i], 5, -6);
$tmp_str = highlight_string(implode("",explode("\\",$tmp_str)), true);
$tmp_str = str_replace('font color="', 'span style="color:', $tmp_str);
$tmp_str = str_replace('font', 'span', $tmp_str);
$tmp_str = (get_magic_quotes_gpc()) ? addslashes($tmp_str) : NULL;
$bb2html = str_replace("***ccc_string***$i", $tmp_str, $bb2html);
}
$bb2html = implode("",explode("\\",$bb2html));
return $bb2html;
}
谢谢!
答案 0 :(得分:1)
你可以考虑两个大问题。
考虑缓存: 您可以将结果缓存到memcache之类的内容中 或者,您可以对输入进行转换并将HTML存储在数据库中并使用它。
使用PECL扩展。 http://pecl.php.net/package/bbcode 这在C中完成将比您的实现更快。