venuko
01-04-2009, 20:36
Есть класс:
class highlighter
{
private $_string;
private $_words;
private $_opentags;
private $_usedTags = array();
public function __construct( $string, $words, $opentags )
{
$this->_string = $string;
$this->_words = $words;
$this->_opentags = $opentags;
}
private function countWordLength( $wordForms )
{
$formsNum = count( $wordForms );
$len = 0;
for( $j = 0; $j < $formsNum; $j++ )
{
$len += strlen( $wordForms[$j] );
}
$len = $len / $formsNum;
return $len;
}
private function swap( &$var1, &$var2 )
{
$temp = $var1;
$var1 = $var2;
$var2 = $temp;
}
public function prepareWordArray()
{
$wordsNum = count( $this->_words );
$words = $this->_words;
$opentags = &$this->_opentags;
$closetags = &$this->_closetags;
$n = 1;
while( $n != 0)
{
$n = 0;
for( $i = 0; $i < ( $wordsNum - 1 ); $i++ )
{
$len1 = $this->countWordLength( $words[$i] );
$len2 = $this->countWordLength( $words[$i + 1] );
if( $len1 < $len2 ) {
$this->swap( &$words[$i], $words[$i + 1] );
$this->swap( &$opentags[$i], $opentags[$i + 1] );
$n++;
}
}
}
$this->_words = $words;
}
private function isWord( $pos, $len)
{
$chars = ".?()[]\"',/\\ !@#$%^&*{}<>`~№;:?";
$string = $this->_string;
$a = $b = true;
if ($pos > 1) {
if (strpos($chars, $string[$pos - 1])===false) {
$a = false;
} else {
}
}
if (substr( $string, $pos - 6, 6) == '<used>') {
return false;
}
if( substr( $string, $pos + $len, 7) == '</used>') {
return false;
}
if (isset( $string[$pos + $len] )) {
if (strpos( $chars,$string[$pos + $len] )===false ) {
$b = false;
} else {
}
}
if ($a && $b) {
return true;
} else {
return false;
}
}
public function findWordForms( $wordID )
{
$forms = $this->_words[$wordID];
$formsNum = count( $forms );
$string = &$this->_string;
$minPos = strlen( $string );
$minLen = 0;
$found = false;
for( $i = 0; $i < $formsNum; $i++ )
{
$stringLen = strlen( $string );
$word = $forms[$i];
$pos = 0;
$len = strlen( $word );
$next = false;
while ( ( $pos + $len ) < $stringLen )
{
$pos = stripos( $string, $word, $pos );
if ( $pos === false ) {
break;
}
if ($this->isWord( $pos, $len )) {
if( $pos < $minPos ) {
$minPos = $pos + 6;
$minLen = $len;
$found = true;
}
$word = substr( $string, $pos, $len );
$string = substr_replace( $string, '<used>'.$word.'</used>', $pos, $len )."\n";
$next = true;
break;
} else {
}
$pos += $len;
}
}
if( $found ) {
if (!in_array( $this->_opentags[$wordID], $this->_usedTags )) {
$word = substr( $string, $minPos - 6, $minLen + 13 );
$string = substr_replace( $string, $this->_opentags[$wordID].$word.'</a>', $minPos, $minLen);
$this->_usedTags[] = $this->_opentags[$wordID];
}
}
}
public function highlight()
{
$n = count( $this->_words );
for( $i = 0; $i < $n; $i++ )
{
$this->findWordForms( $i );
}
}
public function getResult()
{
$this->prepareWordArray();
$this->highlight();
$string = & $this->_string;
$string = str_replace( array( '<used>', '</used>'), array( '', '' ), $string );
return $this->_string;
}
}
В массив выводятся слова и ссылки:
$result = $db->sql_query("select tid, title from ".$prefix."_table");
while ($crow=$db->sql_fetchrow($result)) {
$tid=$crow['tid'];
$words[]=array($crow['title']);
$open_tags[]="<a href=\"modules.php?name=Encyclopedia&op=content&tid=$tid\">";
}
Потом в контенте выделяются соотвественные слова из указанного массива выше:
global $words, $open_tags;
$class = new highlighter($text, $words, $open_tags);
echo $class->getResult();
В базе в таблице table всего 1200 записей, но когда грузится страница с контентом и идет эта обработка (выделение слов, оборачивание ссылками), страница грузится очень долго более 20 секунд!
Подскажите пожалуйста, как оптимизировать запрос?
class highlighter
{
private $_string;
private $_words;
private $_opentags;
private $_usedTags = array();
public function __construct( $string, $words, $opentags )
{
$this->_string = $string;
$this->_words = $words;
$this->_opentags = $opentags;
}
private function countWordLength( $wordForms )
{
$formsNum = count( $wordForms );
$len = 0;
for( $j = 0; $j < $formsNum; $j++ )
{
$len += strlen( $wordForms[$j] );
}
$len = $len / $formsNum;
return $len;
}
private function swap( &$var1, &$var2 )
{
$temp = $var1;
$var1 = $var2;
$var2 = $temp;
}
public function prepareWordArray()
{
$wordsNum = count( $this->_words );
$words = $this->_words;
$opentags = &$this->_opentags;
$closetags = &$this->_closetags;
$n = 1;
while( $n != 0)
{
$n = 0;
for( $i = 0; $i < ( $wordsNum - 1 ); $i++ )
{
$len1 = $this->countWordLength( $words[$i] );
$len2 = $this->countWordLength( $words[$i + 1] );
if( $len1 < $len2 ) {
$this->swap( &$words[$i], $words[$i + 1] );
$this->swap( &$opentags[$i], $opentags[$i + 1] );
$n++;
}
}
}
$this->_words = $words;
}
private function isWord( $pos, $len)
{
$chars = ".?()[]\"',/\\ !@#$%^&*{}<>`~№;:?";
$string = $this->_string;
$a = $b = true;
if ($pos > 1) {
if (strpos($chars, $string[$pos - 1])===false) {
$a = false;
} else {
}
}
if (substr( $string, $pos - 6, 6) == '<used>') {
return false;
}
if( substr( $string, $pos + $len, 7) == '</used>') {
return false;
}
if (isset( $string[$pos + $len] )) {
if (strpos( $chars,$string[$pos + $len] )===false ) {
$b = false;
} else {
}
}
if ($a && $b) {
return true;
} else {
return false;
}
}
public function findWordForms( $wordID )
{
$forms = $this->_words[$wordID];
$formsNum = count( $forms );
$string = &$this->_string;
$minPos = strlen( $string );
$minLen = 0;
$found = false;
for( $i = 0; $i < $formsNum; $i++ )
{
$stringLen = strlen( $string );
$word = $forms[$i];
$pos = 0;
$len = strlen( $word );
$next = false;
while ( ( $pos + $len ) < $stringLen )
{
$pos = stripos( $string, $word, $pos );
if ( $pos === false ) {
break;
}
if ($this->isWord( $pos, $len )) {
if( $pos < $minPos ) {
$minPos = $pos + 6;
$minLen = $len;
$found = true;
}
$word = substr( $string, $pos, $len );
$string = substr_replace( $string, '<used>'.$word.'</used>', $pos, $len )."\n";
$next = true;
break;
} else {
}
$pos += $len;
}
}
if( $found ) {
if (!in_array( $this->_opentags[$wordID], $this->_usedTags )) {
$word = substr( $string, $minPos - 6, $minLen + 13 );
$string = substr_replace( $string, $this->_opentags[$wordID].$word.'</a>', $minPos, $minLen);
$this->_usedTags[] = $this->_opentags[$wordID];
}
}
}
public function highlight()
{
$n = count( $this->_words );
for( $i = 0; $i < $n; $i++ )
{
$this->findWordForms( $i );
}
}
public function getResult()
{
$this->prepareWordArray();
$this->highlight();
$string = & $this->_string;
$string = str_replace( array( '<used>', '</used>'), array( '', '' ), $string );
return $this->_string;
}
}
В массив выводятся слова и ссылки:
$result = $db->sql_query("select tid, title from ".$prefix."_table");
while ($crow=$db->sql_fetchrow($result)) {
$tid=$crow['tid'];
$words[]=array($crow['title']);
$open_tags[]="<a href=\"modules.php?name=Encyclopedia&op=content&tid=$tid\">";
}
Потом в контенте выделяются соотвественные слова из указанного массива выше:
global $words, $open_tags;
$class = new highlighter($text, $words, $open_tags);
echo $class->getResult();
В базе в таблице table всего 1200 записей, но когда грузится страница с контентом и идет эта обработка (выделение слов, оборачивание ссылками), страница грузится очень долго более 20 секунд!
Подскажите пожалуйста, как оптимизировать запрос?