idler
Новичок
оптимизация кода - вопрос экспертам
контент сайта хранится в БД
перед выпечатыванием его на страницу нужно сделать автолинковку - т.е. определенные слова сделать ссылками на определенные страницы
Но задача усложнена тем, что если слово находится между определенными тегами, то линковать его не нужно.
долго мучался с регулярными выражениями, наконец понял, что под данную задачу только ими обойтись не получится.
в итоге написал небольшую функцию, которая работает от 5 до 10 секунд, если записей в БД около 200, а тексты по 9-15 тыс. знаков.
помогите оптимизировать , может быть я выбрал абсолютно не правильный алгоритм
вот код:
контент сайта хранится в БД
перед выпечатыванием его на страницу нужно сделать автолинковку - т.е. определенные слова сделать ссылками на определенные страницы
Но задача усложнена тем, что если слово находится между определенными тегами, то линковать его не нужно.
долго мучался с регулярными выражениями, наконец понял, что под данную задачу только ими обойтись не получится.
в итоге написал небольшую функцию, которая работает от 5 до 10 секунд, если записей в БД около 200, а тексты по 9-15 тыс. знаков.
помогите оптимизировать , может быть я выбрал абсолютно не правильный алгоритм
вот код:
PHP:
function ck($a){
$sql="SELECT a.name AS NAME,
a.url AS URL, s.site_id AS SITE
FROM autolink a
INNER JOIN autolink2site s
ON s.link_id=a.id
WHERE length(a.url)>1 and s.site_id='".SITE_ID."'";
$res=mysql_query($sql); // забираем слова , и урлы, на которые линковать
$ar1=$ar=array();
while($r=mysql_fetch_assoc($res)){
$ar1[]='<a class="newstext" style="cursor: default; text-decoration: none;" href="'.$r['URL'].'" >$1</a>';
$ar[]='#('.$r['NAME'].')(?!([^<]*?\>))#is';
//// созданы два массива СЛОВО и УРЛ
}
$l=strlen($a);// длина строки
$o=''; /// измененная-пролинкованная строка
$match=array();
for($i=0;$i<$l;$i++){/// внимание плохой стиль изменение счетчика внутри цикла
$u='';//// временный буфер
while($a[$i]!='<'){/// заливаем во временный , пока не встретим начало тега
$u.=$a[$i];
$i++;
if($i>=$l) break;/// не допускаем выхода за пределы строки
if($a[$i]==='<' && !preg_match('#^\<((a)|(b(!=r))|(h\d)|(strong))#is',substr($a,$i,8),$match)){
// если следующий символ < и он начинает один из запрещенных для линковки тегов
//перебрасываем счетчик еще на один, чтобы не прервать выполнения этого цикла...
$u.=$a[$i];
$i++;
if($i>=$l) break;
}
}
$o.=preg_replace($ar,$ar1,$u);
$u='';
/// здесь символ открывает тег, тен не является запрещенным...
///выполняем замену и сбрасываем временный буфер в возвращаемую переменную
if(($i+1)>=$l) break;
$z=strtolower($match[1]);/// выясняем какой тег открылся, докручиваем счетчик до его закрытия
while(strtolower(substr($a,$i,strlen($z)+2))!='</'.$z){
$u.=$a[$i];
$i++;
if($i>=$l) break;
}
while ($a[$i-1]!='>'){
$u.=$a[$i];
$i++;
if($i>=$l) break;
}
$o.=$u.$a[$i];
/// пошли на следующий виток
}
return $o;
}