Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Практический пример: Облако тегов
 
 автор: golovdinov   (08.06.2007 в 20:02)   письмо автору
 
 

Пару месяцев назад задумался над созданием облака тегов, подобного http://www.habrahabr.ru/tag/ или http://fotki.yandex.ru/tags/. Тема эта сейчас довольно популярная (Веб 2.0 и все такое...), поэтому кому-нибудь да понадобится.
Сначала просто-напросто не представлял как это реализовать, нигде не было практического примера, ни в одно бесплатном скрипте ничего подобного не нашел, но все приходит со временем и недавно я нконец-таки написал скрипт:
<?
// Выбераем из нужной таблицы теги из последних 70-и записей
$get_tags $db->query ("SELECT tags FROM smth_table ORDER BY id DESC LIMIT 70");

// Подсчитываем кол-во (хотя не понимаю зачем я это вставил... аааа! ну это если записей меньше 70 было :))
$count $db->num_rows ($get_tags);

$all_tags "";

// Ставим все теги нижним регистром через запятую
while (list ($tags) = $db->fetch_row ($get_tags)) {
    if (
trim ($tags) != "") {
        
$tag explode (","$tags);
        for (
$i=0$i<count($tag); $i++) $all_tags .= strtolower (trim ($tag[$i])).",";
    }
}
// Удаляем последнюю запятую
if (substr($all_tagsstrlen($all_tags)-1) == ","$all_tags substr($all_tags0strlen($all_tags)-1);

// Разбиваем теги в массив
$tags 0;
$tags explode (","$all_tags);
$tag_count = array ();
$tagname = array ();
$unique_tags = array ();
$count count($tags);

// Вручную вычисляем уникальные теги (чтобы не повторялись при выводе, array_unique () - не работает)
for ($i=0$i<$count$i++) {
    
$like 0;
    for (
$c=0$c<count($unique_tags); $c++) if ($tags[$i] == $unique_tags[$c]) $like++;
    if (
$like == 0array_push ($unique_tags$tags[$i]);
}

// Считаем количество входов уникального тега в массив со всеми тегами
for ($i=0$i<count($unique_tags);  $i++) {
    
$tag trim ($unique_tags[$i]);
    
$tag_count[$i] = 0;
    for (
$c=0$c<$count$c++) if ($tag == trim($tags[$c])) $tag_count[$i]++;
    
// Записываем, чтобы вначале шло количество входов тега, а затем сам тег
    
$tagname[$i] = $tag_count[$i].".".$tag;
}
// Сортируем по количеству входов
sort ($tagname);
// Переворачиваем
$tagname array_reverse ($tagname);
$tags = array ();

// Оставляем 70 самых популярных ткгов
for ($i=0$i<count($tagname); $i++) {
    
array_push ($tags$tagname[$i]);
    if (
$i == 69) break;
}

// Выстраиваем таги так, чтобы сначала шло его имя, а затем кол-во входов
$tagname = array ();
for (
$i=0$i<count($tags); $i++) {
    
$part explode ("."$tags[$i]);
    
array_push ($tagname$part[1].".".$part[0]);
}
// Сортируем по имени
sort ($tagname);

// Разделяем теги и кол-ва их входов на два массива (для удобства)
$tag_count = array ();
$tag_name = array ();
for (
$i=0$i<count($tagname); $i++) {
    
$part explode ("."$tagname[$i]);
    
array_push ($tag_name$part[0]);
    
array_push ($tag_count$part[1]);
}

print 
"<span class=\"cloud\">";
// Выводим "облаком"
for ($i=0$i<count($tagname); $i++) {
    
$size 31// максимальный размер в пикселях
    // Сравниваем в цикле с кол-вом входов всех других тегов, если есть больше - уменьшаем значение размера
    
for ($c=0$c<count($tagname); $c++) if ($tag_count[$i] < $tag_count[$c]) $size -= 4;
    if (
$size 8$size 8// 8 - наименьший размер
    
print "\n<a href=\"...............{$tag_name[$i]}\" style=\"font-size:{$size}px;\">{$tag_name[$i]}</a> ";
}
print 
"</span>";
?>


Примечание: теги хранятся в виде tag, тег, что-то там, smth (т.е. через запятую)

   
 
 автор: DDK   (21.03.2008 в 02:36)   письмо автору
 
   для: golovdinov   (08.06.2007 в 20:02)
 

Имхо очень неоптимальный метод.

Я бы сделал так:

Создаётся таблица тегов с тремя полями (обзовём её tags_table):
----------------------
| id | sourceid | tag |
----------------------


При добавлении записи в таблицу данных мы сразу разбиваем введённую строку с тегами на отдельные теги и заносим каждый из них в БД, указывая в sourceid идентификатор записи в таблице данных, содержащей этот тег.

Потом при формировании облака тегов делаем простой запрос на подобии:
SELECT tag, count(sourceid) FROM tags_table GROUP BY sourceid


И формируем облако тегов.

Выбирать нужные записи из таблицы данных, помеченые выбранным тегом тоже очень просто:

Сначала выбираем из гашей таблицы тегов ID всех записей в таблице данных, содержащих выбранный тег:
SELECT sourceid FROM tags_table WHERE tag='выбраный тег' ORDER BY чему-то там

Теперь сгребаем все полученные sourceid в массив и выбираем уже из таблицы данных нужные нам записи так:
SELECT * FROM data_table WHERE sourceid IN(тут распечатываем массив с нашими sourceid)


Поправьте, если что не так.

Ваш метод кажется мне ужасным (извините за столь резкую критику), ибо сгребать каждый раз из базы все теги, да еще и парсить их каждый раз (разбивать по запятой) - это виселица для сервера :)) А если тегов 10000 ?

   
 
 автор: mihdan   (21.03.2008 в 12:54)   письмо автору
 
   для: golovdinov   (08.06.2007 в 20:02)
 

Код можно упростить в десятки раз

>// Удаляем последнюю запятую
>if (substr($all_tags, strlen($all_tags)-1) == ",") $all_tags = substr($all_tags, 0, strlen($all_tags)-1);


<?
$all_tags 
trim($all_tags',');
?>

   
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования