Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр 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_tags, strlen($all_tags)-1) == ",") $all_tags = substr($all_tags, 0, strlen($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 == 0) array_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 Яндекс.Метрика Яндекс цитирования