|
|
|
| Пару месяцев назад задумался над созданием облака тегов, подобного 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 (т.е. через запятую) | |
|
|
|
|
|
|
|
для: 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 ? | |
|
|
|
|
|
|
|
для: 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, ',');
?>
|
| |
|
|
|