Все ленты — последние статьи

Простое облако тегов средствами PHP

В данном уроке мы будем делать простое облако тегов для материалов, которые мы будем заносить в нашу базу. Конечно уже есть большое количество готовых скриптов, но лучше попробовать написать своими руками, чтобы несколько закрепить материал, и возможно узнать что-то новое.

demosourse

В уроках Евгения очень много материала по тому, как добавлять в базу данные, поэтому мы не будем акцентировать на этом внимание и сразу приступим к самому облаку тегов. Допустим у нас есть следующие таблицы в базе:

Следующий фрагмент кода необходимо вставить перед занесением основных данных в базу:
1 if (isset($_REQUEST["keywords"])) {
2 $keywords = $_REQUEST["keywords"];
3 $chars = explode(",", $keywords);
4 $i=0;

 

Здесь мы проверяем наличие введенных пользователем ключевых слов при создании материала, если они есть, то разбиваем их функцией explode() через селекторы "," (запятая, но вы можете использовать любые другие селекторы для того, чтобы в базу можно было заносить словосочетания в которых может содержаться запятая) и заносим все полученные слова в единый массив $chars. Создаем переменную $i и приравниваем ее к 0.
01 do {
02 $result_chars = trim($chars[$i]);
03 $result_choice_up = mysql_query("SELECT tag_name, count FROM tags WHERE tag_name='$result_chars'");
04 if(mysql_num_rows($result_choice_up)>0) {
05 $myrow_choice_up = mysql_fetch_array($result_choice_up);
06 $new_count = $myrow_choice_up["count"]+1;
07 $result = mysql_query ("UPDATE tags SET count='$new_count' WHERE tag_name='$result_chars'");
08 $i++;
09 }
10 else {
11 $result = mysql_query("INSERT INTO tags (tag_name, count) VALUES ('$result_chars', 1)",$db);
12 $i++;
13 }}
14 while ($chars[$i]!="");

Запускаем цикл, где мы в таблицу базы tags добавляем полученные функцией explode() ключевые слова.

В $result_chars заносим избавленное от пробелов по краям значение $chars[$i], чтобы у нас не получались в базе на первый взгляд дублированные теги. В случае если такое ключевое слово уже было, то мы увеличиваем показатель count в базе на 1, если не было ключевого слова, то добавляем его в базу с показателем count =1. Переменную $i увеличиваем на 1. Данный цикл мы выполняем до тех пор пока $chars[$i] не станет равной пустой записи.

Закрываем внешний цикл:
1 }else $keywords = "";

Теперь там где нам необходимо вывести наше облако тегов вставляем такой код:
01 $result_tags = mysql_query("SELECT * FROM tags ORDER BY tag_name");
02 $myrow_tags = mysql_fetch_array($result_tags);
03 echo "<ul id='cloud_tag'>";
04 do {
05 $size_font = $myrow_tags["count"]/10+11;
06 printf("
07 <li style='font-size:%spx'><a title='количество материалов: %s' href='?tag=%s'>%s</a></li>
08 ",$size_font,$myrow_tags["count"],$myrow_tags["tag_name"],$myrow_tags["tag_name"]);
09 }
10 while ($myrow_tags = mysql_fetch_array($result_tags));
11 echo "</ul>";

Тут мы формируем простой список, для каждого элемента списка создаем стиль font-size куда мы будем передавать расчет размера текста, в зависимости от значения count в таблице tags. Можете попробовать подставить свои значения, чтобы подобрать более удобные размеры шрифта. Я остановился на исходном 11 размере.

Чтобы все это прилично смотрелось можно добавить немного стилей:
01 #cloud_tag {
02 margin:2px;
03 width:210px;
04 }
05 #cloud_tag li{
06 float:left;
07 list-style:none;
08 font:Arial, Helvetica, sans-serif;
09 margin-left:5px;
10 }

В стилях мы ставим для каждого элемента li обтекание слева, а само облако делаем шириной 210 пикселей. Отлично облако готово, теперь необходимо заставить работать вывод материалов при клике на элементы облака.
01 if (isset($_REQUEST["tag"])) {
02 $search_tag = $_REQUEST["tag"];
03 echo "<p>Вы выбираете по ключевому слову: <strong>".$search_tag."</strong> <a href='allmaterials.php'>Все материалы</a></p>";
04 $result_material = mysql_query("SELECT * FROM materials");
05 $myrow_mat = mysql_fetch_array($result_material);
06 do {
07 $tags = $myrow_mat["keywords"];
08 $search = "/".$search_tag."/";
09 if (preg_match_all($search,$tags,$array)) {
10 $text = strip_tags($myrow_mat["text"]);
11 $text = substr($myrow_mat["text"],0,150);
12 printf ("
13 <div id='news_block'>
14 <div><a href='material.php?id=%s'>%s</a></div>
15 <p>%s…</p>
16 <p align='right'><a href='material.php?id=%s'><span>Подробнее…</span></a></p>
17 </div>
18 ",$myrow_mat["id"],$myrow_mat["title"],$text,$myrow_mat["id"]);
19 }
20 }
21 while ($myrow_mat = mysql_fetch_array($result_material));}
22 else {просто выводим все материалы}

Проверяем наличие переданной переменной $tag, эта переменная у нас будет частью регулярной функции, по которой скрипт будет искать наличие вхождения тега в поле keywords в таблице базы materials. Если совпадение произошло, то выводится краткий дескрипт материала, если нет, то материал соответственно невидим.

Таким же способом можно удалять теги в случае, если материал был удален из базы. Точно так же используем функцию explode() и далее, либо отнимаем 1 у каждого тега материала, либо полностью удаляем тег. Как вариант, тег можно оставить в базе, но приравнять его к 0, а в само облако не выводить теги, которые равны 0.

Вариант достаточно гибкий и его можно перевести на рельсы AJAX для повышения производительности сайта, ведь если у вас не 10 материалов как в примере, а сотни, то перезагрузка страницы может занять достаточно долгий период времени.