Как создать облако тегов для своего сайта на PHP

Владимир | | CodeIgniter, HTML, PHP, Web разработка.

Облако тегов

В этой статье я расскажу и, естественно, покажу пример создания облака тегов для сайта (блога). Основные инструменты – PHP и фреймворк CodeIgniter (подойдет любой другой).

Но, прежде всего, хочу поблагодарить Delchyve за идею.

Итак, переходим к делу.

Вы, конечно, знаете, что облако тегов используется на многих сайтах (в основном это блоги) как элемент навигации. По-сути, облако тегов – это набор ссылок с ключевыми словами, рядом с которыми обычно пишут количество постов, которые относятся к данному тегу.

Чтобы сфокусировать внимание посетителя на наиболее актуальных темах, размер шрифта тегов в облаке меняют в зависимости от количества постов, которые к нему относятся.

Если ваш сайт (блог) использует какую-нибудь CMS, например, WordPress, Joomla и т.п., то вы без труда найдете плагины, которые сами создадут облако тегов на основе ваших данных, а вам останется только разместить его в шаблоне сайта.

Но мы рассмотрим ситуацию, когда сайт пишется «с нуля» и вам нужно сформировать облако ручками 🙂 .

Прежде всего, вы должны четко понимать, что данные для создания облака мы получаем из базы данных, а способ их получения зависит от ее структуры (взаимосвязей между таблицами).

В качестве примера попробуем сформировать фрагмент такой базы данных для блога.

Мы хотим, чтобы пользователь мог присваивать любое количество тегов любому из постов. При этом один и тот же тег может быть присвоен нескольким постам. В принципе, можно разместить все эти данные внутри одной таблицы, т.е. сделать поле, в котором будут перечислены все теги через запятую. Но такой подход имеет несколько очень существенных недостатков.

Во-первых, информация в таблице будет дублироваться (если один и тот же тег присвоен нескольким постам).
Во-вторых, для поиска придется использовать предложение LIKE, а это очень неэффективно с точки зрения производительности.
В-третьих, простая операция вывода списка тегов потребует ряд дополнительных операций (разбивку строк на лексемы, формирования массива с тегами и т.д.).

Поэтому гораздо удобнее хранить посты и теги в разных таблицах.

Допустим, наша таблица с постами (назовем ее posts) содержит такие поля:

1) id – первичный ключ;
2) title – заголовок;
3) text – текст поста;
4) date – дата;
и др.

А таблица с тегами (tags):

1) id – первичный ключ;
2) tag – имя тега.

Теперь нужно связать таблицы между собой. Т.к. в данном случае мы имеем отношение «многие-ко-многим» (один пост и тот же пост может иметь несколько тегов, а один и тот же тег можно присвоить нескольким постам), то для его реализации нам потребуется еще одна таблица. Она будет называться posts_tags и иметь следующие поля:

1) id – первичный ключ;
2) postid – внешний ключ (связывает запись с таблицей posts);
3) tagid – внешний ключ (связывает запись с таблицей tags).

Каждая запись в таблице posts_tags определяет одну взаимосвязь между таблицами posts и tags.

На рисунке изображены связи между таблицами

Структура базы данных

Рассмотрим, как она заполняется.

Допустим в таблицах posts и tags уже есть какие-то данные.

posts

id text title date
1 post 1 title 1 2008-05-01 19:40:08
2 post 2 title 2 2008-05-01 19:40:39
3 post 3 title 3 2008-05-01 19:41:08

tags

id tag
1 php
2 html
3 java
4 ajax
5 JavaScript

Чтобы присвоить тег html второму посту (post 2), то в таблице posts_tags нужно создать запись:

postid = 2
tagid = 2

Хотим к этому же посту добавить еще тег JavaScript? Не проблема. Добавляем в posts_tags еще одну запись:

postid = 2
tagid = 5

Таким образом, используя эту таблицу, мы может создать любое количество взаимосвязей между постами и тегами.

Теперь переходим к реализации.

Как я и обещал, в качестве фреймворка мы будем использовать CodeIgniter. Но это совершенно не обязательно. Вы сможете легко переписать пример, используя только стандартные функции PHP.

Начнем с контроллера (main.php).

class Main extends Controller {
	function Main() {
		parent::Controller();
		$this->load->database();
	}
	function index() {
		$this->load->model('tagcloudmodel');
		$pageData['tagcloud'] = $this->tagcloudmodel->getTagCloudData();

		$this->load->view('header');
		$this->load->view('tagcloud', $pageData);
		$this->load->view('footer');
	}
}

Как видите, он имеет всего один метод – index(), который будет создавать страницу с облаком.

В конструкторе мы загрузили библиотеку для работы с базой данных (строка 4), а в начале метода index() – модель tagcloudmodel (о ней чуть позже).

После этого мы вызываем метод getTagCloudData() модели, который возвращает нам массив со всей информацией, необходимой для построения облака. И затем показываем страницу (строки 10-13).

Отдельно хочу отметить, что для отображения облака нам нужны.

1) Перечень всех тегов. Не проблема, просто читаем содержимое таблицы tags.

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

Теперь рассмотрим модель (tagcloudmodel.php)

class TagCloudModel extends Model {
	function TagCloudModel() {
		parent::Model();
	}

	function getTagCloudData() {
		$qGetCloud = "SELECT tags.tag, COUNT(posts_tags.tagid) AS posts_count".
					" FROM posts_tags LEFT JOIN tags ON posts_tags.tagid=tags.id".
					" GROUP BY tags.id";
		$res = $this->db->query($qGetCloud);
		if ($res->num_rows() == 0) {
			return false;
		}
		else {
			return $res->result_array();
		}
	}
}

Здесь тоже только один метод (не считая конструктора). В нем мы выполняем один запрос к базе данных и, если данные найдены, возвращаем массив с результатами.

Т.к. запрос выполняет основную часть работы, рассмотрим его подробнее. Условно запрос можно разбить на три части.

1) После предложения SELECT мы указываем, какие данные хотим получить (строка 7). Это имя тега и количество постов, которым он присвоен. (Для подсчета постов используем агрегатную функцию COUNT).

2) Указываем, из каких таблиц брать данные. Здесь мы используем «левое объединение» таблицы posts_tags с таблицей tags, а в условии объединения указываем, что posts_tags.tagid должен быть равен tags.id. Таким образом, MySQL для каждой записи в таблице posts_tags найдет соответствующую запись в таблице tags и подставит соответствующее имя тега.

3) Группируем поля по первичному ключу тега (строка 9). После этой операции в результирующем массиве теги повторяться не будут, а функция COUNT подсчитает, сколько раз встретился каждый тег.

Примечание. Этот запрос вернет только те теги, которые присвоены хотя бы одному посту (т.е. существует запись в таблице posts_tags). Если по каким-то причинам вам нужно вывести все теги (включая те, для которых нет постов), измените порядок объединения таблиц в запросе: .....FROM tags LEFT JOIN posts_tags ON........

Данные мы получили, переходим к созданию представлений.

Для этого примера я сделал 3 представления (заголовок, хвостовик и основная часть). Наверное, это перебор 🙂 , но для реальных сайтов заголовок и хвостовик обычно повторяются для нескольких страниц, поэтому лучше их сразу отделить.

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

header.php

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Облако тегов</title>
</head>
<body>

footer.php

</body>
</html>

А вот на основной части (tagcloud.php) остановимся подробнее.

if ($tagcloud === FALSE) {
	echo "Данные не найдены";
}
else {
	$min = $tagcloud[0]['posts_count'];
	$max = $tagcloud[0]['posts_count'];
	for ($i = 1; $i < count($tagcloud); $i++) {
		if ($tagcloud[$i]['posts_count'] > $max) {
			$max = $tagcloud[$i]['posts_count'];
		}
		if ($tagcloud[$i]['posts_count'] < $min) {
			$min = $tagcloud[$i]['posts_count'];
		}
	}
	$minSize = 70;
	$maxSize = 150;
	foreach ($tagcloud as $item) {
	    if ($min == $max) {
	        $fontSize = round(($maxSize - $minSize) / 2 + $minSize);
        }
        else {
		    $fontSize = round((($item['posts_count'] - $min)/($max - $min)) * ($maxSize - $minSize) + $minSize);
        }
		echo "<span style=\"font-size:".$fontSize."%\">".$item['tag']." (".$item['posts_count'].") </span>";
	}
}

Здесь мы проверяем, найдены ли данные (строки 1-3) и если найдены, начинаем формировать облако.

Прежде всего, находим теги, которые присвоены минимальному и максимальному количеству постов (строки 5-14).

После этого задаем минимальный и максимальный размер шрифта (в данном случае я задал 70% и 150%).

Теперь формируем цикл, который будет выводить теги (строки 17-26). Внутри цикла мы рассчитываем размер шрифта текущего тега (строки 18-23). Тег, для которого найдено минимальное число постов, будет иметь размер 70%, а тег с максимальным числом постов – 150%. Для остальных тегов будут рассчитаны промежуточные значения в зависимости от количества постов.

Результат показан на скриншоте.

Облако тегов

Естественно, для реального блога, каждый тег будет представлять собой ссылку, которая ведет на соответствующую страницу. Но это отдельная тема.

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

Кстати, ради интереса посмотрите структуру базы данных WordPress. Думаю, вы легко найдете нужные таблицы.

Удачи!

  • Владимр, огромное спасибо за пост 🙂
    Внесли ясность.

  • Владимр, огромное спасибо за пост 🙂
    Внесли ясность.

  • MAX

    Интересно. 🙂 Я как раз на днях доделывал «свои» облака меток. Так что немного позанудствую. 😉

    В рамках статьи все сделано правильно, но вот с точки зрения конечного продукта, использование какой-то отдельной таблицы не совсем разумно. Метки — это частный случай любой другой информации для любой записи. В простонародье — это meta. У меня например используется такая структура (только часть полей, имеющее отношение в данному примеру):

    meta_id — id-мета автоинкремент
    meta_key — ключ, например 'tags'
    meta_id_obj — id связанной таблицы, например номер записи
    meta_value — значение мета

    Таблица записей/страниц имеет:
    page_id — номер записи
    и т.д.

    То есть meta_key может быть чем угодно, например можно указать автора, источник, ключевые слова, описание, title страницы и т.д.

    При добавлении меток к записи в редакторе есть отдельное поле, где следует указать метки через запятую. При добавлении в базу эта строка разбивается на отдельные элементы и добавляется в таблицу meta. C одной стороны мы получаем дублирование меток в одной таблице, но при внимательном рассмотрении, всё равно придется хранить либо сами метки, либо какую-то связующую таблицу (в вашем случае posts_tags). В моем случае нет проблем с добавлениием одинаковых меток: удаляются старые, потом insert. В вашем же случае добавление несколько сложней, поскольку метка уже может существовать и нужно найти её id и связывать таблицы по этому номеру. У вас подход больше подходит не для меток, а для предопределенных рубрик, где их удобней не вводить вручную, а отмечать (checkbox). (У меня рубрики как раз по такому принципу и организованы. В WordPress также, только там это называется таксономией.)

    Для получения меток одной записи выполняется простой SQL:

    $CI->db->select('meta_value');
    $CI->db->where( array ( 'meta_key' => 'tags', 'meta_id_obj' => номер записи ) );
    $query = $CI->db->get('meta');

    Для получения массива всех меток в виде массива [метка] => колво:

    $CI->db->select('meta_value, COUNT(meta_value) AS meta_count');
    $CI->db->where( array ( 'meta_key' => 'tags' ) );
    $CI->db->join('page', 'page.page_id = meta.meta_id_obj' );
    $CI->db->group_by('meta_value');
    $query = $CI->db->get('meta');

    // переделаем к виду [метка] = кол-во
    if ($query->num_rows() > 0)
    {
    $tags = array();
    foreach ($query->result_array() as $row)
    $tags[$row['meta_value']] = $row['meta_count'];
    return $tags;
    }
    else return array();

    С таким массивом несколько проще работать при выводе: например конечная функция формирования облака получается такой:

    asort($tagcloud);
    $min = reset($tagcloud);
    $max = end($tagcloud);

    $minSize = 70;
    $maxSize = 150;
    $out = '';

    // здесь можно задать сортировку элементов
    arsort($tagcloud); // большие метки в начале

    foreach ($tagcloud as $tag => $count) {
    $fontSize = round((($count - $min)/($max - $min)) * ($maxSize - $minSize) + $minSize);
    $out .= "" . $tag . " (" . $count . ") ";
    }

    return $out;

    Вот примерно так. 🙂

    • Да, читая такие комментарии начинаешь понимать смысл фразы user generated content 🙂

      Если серьезно, мне ваш пример очень понравился. Полностью логичное продолжение темы.

      Но я тоже попридираюсь 🙂

      В моем случае нет проблем с добавлением одинаковых меток: удаляются старые, потом insert.

      Этот момент я хочу уточнить.
      Например, есть метка:
      meta_id = 5
      meta_key = ‘tags’
      meta_id_obj = 4 (id поста которому присвоена данная метка)
      meta_value = 'my_tag'
      Нужно добавить еще одну метку для этого поста. Для этого сначала удаляем все метки с meta_id_obj = 4, а затем вставляем новый список? Правильно?
      Если да, то нужна еще одна операция. Предварительно нужно получить список всех меток и добавить их в поле редактирования.

      всё равно придется хранить либо сами метки, либо какую-то связующую таблицу

      Да, но в связующей таблице поля имеют тип INT, а не VARCHAR, поэтому получаем выигрыш в размере базы.
      Кстати, я не очень удачно создал эту таблицу (posts_tags). Лучше сделать составной первичный ключ и не делать поля id вообще:
      PRIMARY KEY (postid, tagid)

      У вас подход больше подходит не для меток, а для предопределенных рубрик, где их удобней не вводить вручную, а отмечать (checkbox)

      Лично я очень часто когда добавляю закладки в memori.ru просто кликаю по существующим тегам чтобы не вводить их вручную, потому что можно легко ошибиться одним символом и получить две разные метки (тот же checkbox, вид сбоку 🙂 )

      asort($tagcloud);

      Сортировка вещь хорошая, но «кушает» ресурсов значительно больше чем просто поиск минимального и максимального значений. Хотя, обычно меток не много и врядли это заметно повлияет на общую производительность. Тем более если стоит задача выводить метки с максимальным количеством элементов первыми (тут без сортировки обойтись не получится, но можно выполнить ее в запросе к БД).

      • MAX

        >> Например, есть метка: …
        >> Нужно добавить еще одну метку для этого поста. Для этого сначала удаляем все метки с meta_id_obj = 4, а затем вставляем новый список? Правильно?
        >> Если да, то нужна еще одна операция. Предварительно нужно получить список всех меток и добавить их в поле редактирования.

        Не совсем так. Получать существующие метки перед их обновлением (в бд) не нужно. В sql-запросе достаточно указать meta_key=tags и meta_id_obj=номер записи. Дальше delete('meta').

        То есть просто удаляются ВСЕ метки данной записи.

        Сам же процесс редактирования (юзером) может происходить по разному. У меня это просто отдельное поле, где через запятую выводятся все метки к данной записи. Поэтому юзер сразу видит все текущие метки этой записи и правит их как угодно. Когда он нажимает «Сохранить», метки передаются в виде строки. Перед insert строка разбивается в массив, обходя который и выполняется insert в базу.

        >> Да, но в связующей таблице поля имеют тип INT, а не VARCHAR, поэтому получаем выигрыш в размере базы.

        Абсолютно верно. Но все-таки метки не такие большие, поэтому разница в абсолютном выражении будет не велика. Просто на мой взгляд если речь идет именно о метках, то нельзя их приравнивать к предопределенным рубрикам, которые как раз и требуют связующей таблицы. meta более универсальна — именно это я пытаюсь донести. 🙂

        >> Лично я очень часто когда добавляю закладки в memori.ru просто кликаю по существующим тегам чтобы не вводить их вручную, потому что можно легко ошибиться одним символом и получить две разные метки (тот же checkbox, вид сбоку 🙂 )

        Признаться я не вижу разницы — можно сделать кликабельные существующие метки. Хоть чекбоксами. 🙂

        >> Сортировка вещь хорошая, но “кушает” ресурсов значительно больше чем просто поиск минимального и максимального значений.

        Честно говоря, первый раз про такое слышу. Почему-то мне всегда казалось, что «родные» функции PHP работают быстрей «самописных». 😉

        • То есть просто удаляются ВСЕ метки данной записи.

          Значит если статья уже имеет 5 тегов и я хочу добавить еще 1, то сначала будут удалены 5 записей из БД, а затем вставлены новые 6? Выглядит немного неэкономно, но с другой стороны всего 2 запроса…

          нельзя их приравнивать к предопределенным рубрикам, которые как раз и требуют связующей таблицы. meta более универсальна

          Полностью согласен. Но что мешает использовать meta и связующую таблицу? Поле id в любом случае уникально. Связующая таблица может использоваться только для связи тегов (т.е. меток для которых meta_key=tags) с постами, а остальные meta будут использоваться без нее.
          Хотя, по-моему это все не принципиально, работать будут оба варианта. А чтобы сделать оптимизацию по скорости и потреблению ресурсов, нужно тестировать оба варианта в одинаковых условиях. Не знаю насколько это оправданно.

          «родные» функции PHP работают быстрей «самописных»

          Да, тут я погорячился 🙂 Хотя алгоритм сортировки в любом случае сложнее.

        • MAX

          >> Но что мешает использовать meta и связующую таблицу? Поле id в любом случае уникально. Связующая таблица может использоваться только для связи тегов (т.е. меток для которых meta_key=tags) с постами, а остальные meta будут использоваться без нее.

          А зачем? Связующая таблица просто не нужна — ведь вполне достаточно одного запроса к одной таблице: в meta уже есть номер записи. 😉

          Кстати, когда-то у меня спрашивали как сделать два-три облака тэгов на WordPress. Вроде как одно для города, другое страны. В вашем случае задача опять сведется к ведению еще двух таблиц. В моем достаточно указать другой meta_key.

          Что касается производительности и ресурсоемкости, то тут вопрос сложный. Для себя я решил, что основной упор следует делать на кэширование. В этом случае функция может вообще не выполняться, а сразу вывести готовый результат из кэша. Например у меня облако меток сейчас целиком кэшируется.

          И еще по функции. Нужно добавить проверку, а то деление на ноль возможно (при выводе).

          if ($max == $min) $max++;

        • В вашем случае задача опять сведется к ведению еще двух таблиц

          Не, еще две таблицы — это перебор. В такой ситуации я бы добавил еще одно поле в таблицу tags (posts_tags остается без изменений), т.е. структура стала бы очень похожа на ваш вариант 🙂 .
          Ну не нравится мне дублирование данных в таблице 🙂 .

          кеширование

          Да, пожалуй, от него и будет основной прирост производительности.

          if ($max == $min) $max++;

          Все время что-то забываю 😳 . Спасибо!

      • Opanas

        Лучше индекс делать так PRIMARY KEY (tagid, postid)

        тогда будет использоваться индекс при поиске по tagid.

        А в остальном, спасибо за статью и комменты )

        • Rin

          Можно по подробнее? почему?

        • 1) в таблице на одно поле будет меньше.
          2) каждое сочетание tagid и postid должно быть уникальным, если сделать его первичным ключом, то движок mysql будет автоматически следить за выполнением этого требования.

    • При добавлении меток к записи в редакторе есть отдельное поле, где следует указать метки через запятую. При добавлении в базу эта строка разбивается на отдельные элементы и добавляется в таблицу meta.

      Подскажите пожалуйста PHP код, чтоб разбить строку на отдельные теги, разделенные запятыми.

      • $test = 'раз, два, три четыре';
        //разбиваем строку
        $res = explode(',', $test);
        //удаляем лишние пробелы
        for ($i = 0; $i < count($res); $i++) {
        $res[$i] = trim($res[$i]);
        }

        • спасибо за помощь

        • Big_Shark

          $test = 'раз, два, три четыре';
          $tags=array_map('trim',explode(',',$test));
          Теперь тоже самое в 1 строчку)

  • MAX

    Интересно. 🙂 Я как раз на днях доделывал «свои» облака меток. Так что немного позанудствую. 😉

    В рамках статьи все сделано правильно, но вот с точки зрения конечного продукта, использование какой-то отдельной таблицы не совсем разумно. Метки — это частный случай любой другой информации для любой записи. В простонародье — это meta. У меня например используется такая структура (только часть полей, имеющее отношение в данному примеру):

    meta_id — id-мета автоинкремент
    meta_key — ключ, например 'tags'
    meta_id_obj — id связанной таблицы, например номер записи
    meta_value — значение мета

    Таблица записей/страниц имеет:
    page_id — номер записи
    и т.д.

    То есть meta_key может быть чем угодно, например можно указать автора, источник, ключевые слова, описание, title страницы и т.д.

    При добавлении меток к записи в редакторе есть отдельное поле, где следует указать метки через запятую. При добавлении в базу эта строка разбивается на отдельные элементы и добавляется в таблицу meta. C одной стороны мы получаем дублирование меток в одной таблице, но при внимательном рассмотрении, всё равно придется хранить либо сами метки, либо какую-то связующую таблицу (в вашем случае posts_tags). В моем случае нет проблем с добавлениием одинаковых меток: удаляются старые, потом insert. В вашем же случае добавление несколько сложней, поскольку метка уже может существовать и нужно найти её id и связывать таблицы по этому номеру. У вас подход больше подходит не для меток, а для предопределенных рубрик, где их удобней не вводить вручную, а отмечать (checkbox). (У меня рубрики как раз по такому принципу и организованы. В WordPress также, только там это называется таксономией.)

    Для получения меток одной записи выполняется простой SQL:

    $CI->db->select('meta_value');
    $CI->db->where( array ( 'meta_key' => 'tags', 'meta_id_obj' => номер записи ) );
    $query = $CI->db->get('meta');

    Для получения массива всех меток в виде массива [метка] => колво:

    $CI->db->select('meta_value, COUNT(meta_value) AS meta_count');
    $CI->db->where( array ( 'meta_key' => 'tags' ) );
    $CI->db->join('page', 'page.page_id = meta.meta_id_obj' );
    $CI->db->group_by('meta_value');
    $query = $CI->db->get('meta');

    // переделаем к виду [метка] = кол-во
    if ($query->num_rows() > 0)
    {
    $tags = array();
    foreach ($query->result_array() as $row)
    $tags[$row['meta_value']] = $row['meta_count'];
    return $tags;
    }
    else return array();

    С таким массивом несколько проще работать при выводе: например конечная функция формирования облака получается такой:

    asort($tagcloud);
    $min = reset($tagcloud);
    $max = end($tagcloud);

    $minSize = 70;
    $maxSize = 150;
    $out = '';

    // здесь можно задать сортировку элементов
    arsort($tagcloud); // большие метки в начале

    foreach ($tagcloud as $tag => $count) {
    $fontSize = round((($count - $min)/($max - $min)) * ($maxSize - $minSize) + $minSize);
    $out .= "" . $tag . " (" . $count . ") ";
    }

    return $out;

    Вот примерно так. 🙂

    • Да, читая такие комментарии начинаешь понимать смысл фразы user generated content 🙂

      Если серьезно, мне ваш пример очень понравился. Полностью логичное продолжение темы.

      Но я тоже попридираюсь 🙂

      В моем случае нет проблем с добавлением одинаковых меток: удаляются старые, потом insert.

      Этот момент я хочу уточнить.
      Например, есть метка:
      meta_id = 5
      meta_key = ‘tags’
      meta_id_obj = 4 (id поста которому присвоена данная метка)
      meta_value = 'my_tag'
      Нужно добавить еще одну метку для этого поста. Для этого сначала удаляем все метки с meta_id_obj = 4, а затем вставляем новый список? Правильно?
      Если да, то нужна еще одна операция. Предварительно нужно получить список всех меток и добавить их в поле редактирования.

      всё равно придется хранить либо сами метки, либо какую-то связующую таблицу

      Да, но в связующей таблице поля имеют тип INT, а не VARCHAR, поэтому получаем выигрыш в размере базы.
      Кстати, я не очень удачно создал эту таблицу (posts_tags). Лучше сделать составной первичный ключ и не делать поля id вообще:
      PRIMARY KEY (postid, tagid)

      У вас подход больше подходит не для меток, а для предопределенных рубрик, где их удобней не вводить вручную, а отмечать (checkbox)

      Лично я очень часто когда добавляю закладки в memori.ru просто кликаю по существующим тегам чтобы не вводить их вручную, потому что можно легко ошибиться одним символом и получить две разные метки (тот же checkbox, вид сбоку 🙂 )

      asort($tagcloud);

      Сортировка вещь хорошая, но «кушает» ресурсов значительно больше чем просто поиск минимального и максимального значений. Хотя, обычно меток не много и врядли это заметно повлияет на общую производительность. Тем более если стоит задача выводить метки с максимальным количеством элементов первыми (тут без сортировки обойтись не получится, но можно выполнить ее в запросе к БД).

      • MAX

        >> Например, есть метка: …
        >> Нужно добавить еще одну метку для этого поста. Для этого сначала удаляем все метки с meta_id_obj = 4, а затем вставляем новый список? Правильно?
        >> Если да, то нужна еще одна операция. Предварительно нужно получить список всех меток и добавить их в поле редактирования.

        Не совсем так. Получать существующие метки перед их обновлением (в бд) не нужно. В sql-запросе достаточно указать meta_key=tags и meta_id_obj=номер записи. Дальше delete('meta').

        То есть просто удаляются ВСЕ метки данной записи.

        Сам же процесс редактирования (юзером) может происходить по разному. У меня это просто отдельное поле, где через запятую выводятся все метки к данной записи. Поэтому юзер сразу видит все текущие метки этой записи и правит их как угодно. Когда он нажимает «Сохранить», метки передаются в виде строки. Перед insert строка разбивается в массив, обходя который и выполняется insert в базу.

        >> Да, но в связующей таблице поля имеют тип INT, а не VARCHAR, поэтому получаем выигрыш в размере базы.

        Абсолютно верно. Но все-таки метки не такие большие, поэтому разница в абсолютном выражении будет не велика. Просто на мой взгляд если речь идет именно о метках, то нельзя их приравнивать к предопределенным рубрикам, которые как раз и требуют связующей таблицы. meta более универсальна — именно это я пытаюсь донести. 🙂

        >> Лично я очень часто когда добавляю закладки в memori.ru просто кликаю по существующим тегам чтобы не вводить их вручную, потому что можно легко ошибиться одним символом и получить две разные метки (тот же checkbox, вид сбоку 🙂 )

        Признаться я не вижу разницы — можно сделать кликабельные существующие метки. Хоть чекбоксами. 🙂

        >> Сортировка вещь хорошая, но “кушает” ресурсов значительно больше чем просто поиск минимального и максимального значений.

        Честно говоря, первый раз про такое слышу. Почему-то мне всегда казалось, что «родные» функции PHP работают быстрей «самописных». 😉

        • То есть просто удаляются ВСЕ метки данной записи.

          Значит если статья уже имеет 5 тегов и я хочу добавить еще 1, то сначала будут удалены 5 записей из БД, а затем вставлены новые 6? Выглядит немного неэкономно, но с другой стороны всего 2 запроса…

          нельзя их приравнивать к предопределенным рубрикам, которые как раз и требуют связующей таблицы. meta более универсальна

          Полностью согласен. Но что мешает использовать meta и связующую таблицу? Поле id в любом случае уникально. Связующая таблица может использоваться только для связи тегов (т.е. меток для которых meta_key=tags) с постами, а остальные meta будут использоваться без нее.
          Хотя, по-моему это все не принципиально, работать будут оба варианта. А чтобы сделать оптимизацию по скорости и потреблению ресурсов, нужно тестировать оба варианта в одинаковых условиях. Не знаю насколько это оправданно.

          «родные» функции PHP работают быстрей «самописных»

          Да, тут я погорячился 🙂 Хотя алгоритм сортировки в любом случае сложнее.

        • MAX

          >> Но что мешает использовать meta и связующую таблицу? Поле id в любом случае уникально. Связующая таблица может использоваться только для связи тегов (т.е. меток для которых meta_key=tags) с постами, а остальные meta будут использоваться без нее.

          А зачем? Связующая таблица просто не нужна — ведь вполне достаточно одного запроса к одной таблице: в meta уже есть номер записи. 😉

          Кстати, когда-то у меня спрашивали как сделать два-три облака тэгов на WordPress. Вроде как одно для города, другое страны. В вашем случае задача опять сведется к ведению еще двух таблиц. В моем достаточно указать другой meta_key.

          Что касается производительности и ресурсоемкости, то тут вопрос сложный. Для себя я решил, что основной упор следует делать на кэширование. В этом случае функция может вообще не выполняться, а сразу вывести готовый результат из кэша. Например у меня облако меток сейчас целиком кэшируется.

          И еще по функции. Нужно добавить проверку, а то деление на ноль возможно (при выводе).

          if ($max == $min) $max++;

        • В вашем случае задача опять сведется к ведению еще двух таблиц

          Не, еще две таблицы — это перебор. В такой ситуации я бы добавил еще одно поле в таблицу tags (posts_tags остается без изменений), т.е. структура стала бы очень похожа на ваш вариант 🙂 .
          Ну не нравится мне дублирование данных в таблице 🙂 .

          кеширование

          Да, пожалуй, от него и будет основной прирост производительности.

          if ($max == $min) $max++;

          Все время что-то забываю 😳 . Спасибо!

      • Opanas

        Лучше индекс делать так PRIMARY KEY (tagid, postid)

        тогда будет использоваться индекс при поиске по tagid.

        А в остальном, спасибо за статью и комменты )

        • Rin

          Можно по подробнее? почему?

        • 1) в таблице на одно поле будет меньше.
          2) каждое сочетание tagid и postid должно быть уникальным, если сделать его первичным ключом, то движок mysql будет автоматически следить за выполнением этого требования.

    • При добавлении меток к записи в редакторе есть отдельное поле, где следует указать метки через запятую. При добавлении в базу эта строка разбивается на отдельные элементы и добавляется в таблицу meta.

      Подскажите пожалуйста PHP код, чтоб разбить строку на отдельные теги, разделенные запятыми.

      • $test = 'раз, два, три четыре';
        //разбиваем строку
        $res = explode(',', $test);
        //удаляем лишние пробелы
        for ($i = 0; $i < count($res); $i++) {
        $res[$i] = trim($res[$i]);
        }

        • спасибо за помощь

        • Big_Shark

          $test = 'раз, два, три четыре';
          $tags=array_map('trim',explode(',',$test));
          Теперь тоже самое в 1 строчку)

  • Я у себя добавил в tags число тэгов отдельно как поле, что-бы не делать count каждый раз. Перерасчитывать надо при новой публикации или изменении тэгов.

    • Тоже вариант, вообще с точки зрения оптимизации тут есть над чем поработать.

    • Roosso

      + мне тоже не нравится работа запроса count(*) в таблицу. На лету в массиве и то кажеться лучше считать.

  • Я у себя добавил в tags число тэгов отдельно как поле, что-бы не делать count каждый раз. Перерасчитывать надо при новой публикации или изменении тэгов.

    • Тоже вариант, вообще с точки зрения оптимизации тут есть над чем поработать.

  • Это очень простой функционал тегов, но он вполне справляется со своей задачей. Практически такую же систему хранения я организовал для моего текущего проекта портала-магазина, где помимо прочего в таблице-аналоге «posts_tags» имеется еще два ключа:

    — Component (определяет к какому объекту был присвоен тэг: 'news', 'goods', 'producers', 'blog', 'articles')
    — ID_user — идентификатор пользователя. Возможно значение 0 — это когда суперадмин формирует теги, которые будут доступны всем новым пользователям по-умолчанию и помогает связывать контент.
    —-

    Немного в оффтоп, но не могу не задать вопрос, который может сэкономить мое время:

    Может быть кто-то наталкивался на готовое решение для CI, которое позволяло бы управлять блоками на сайте — всякие опросы, баннеры, меню ну и т.д. Т.е. чтобы глобально не прописывать нужные инструкции в каждом контроллере.

    Не поймите неправильно, я понимаю как это можно сделать 🙂 Но может быть кто-то где-то натыкался на готовые решения. Буду признателен 🙂

    • Может быть кто-то наталкивался на готовое решение для CI

      Честно говоря не сталкивался. Можно поискать на CIForge.
      А вообще этот функционал сильно напоминает CMS.

      • а такое облако тегов можно поставить в партнерский магазин, который парсит товары?

        • Да, можно, но конкретная реализация зависит от того, как сохранены в базе данные о товарах.

        • Sdf

          ываы

        • Asd

          asdfasdf

        • Asdf

          asdf asd f

        • Asdf
        • Asdf
        • Asdf
        • Asdf
  • Это очень простой функционал тегов, но он вполне справляется со своей задачей. Практически такую же систему хранения я организовал для моего текущего проекта портала-магазина, где помимо прочего в таблице-аналоге «posts_tags» имеется еще два ключа:

    — Component (определяет к какому объекту был присвоен тэг: 'news', 'goods', 'producers', 'blog', 'articles')
    — ID_user — идентификатор пользователя. Возможно значение 0 — это когда суперадмин формирует теги, которые будут доступны всем новым пользователям по-умолчанию и помогает связывать контент.
    —-

    Немного в оффтоп, но не могу не задать вопрос, который может сэкономить мое время:

    Может быть кто-то наталкивался на готовое решение для CI, которое позволяло бы управлять блоками на сайте — всякие опросы, баннеры, меню ну и т.д. Т.е. чтобы глобально не прописывать нужные инструкции в каждом контроллере.

    Не поймите неправильно, я понимаю как это можно сделать 🙂 Но может быть кто-то где-то натыкался на готовые решения. Буду признателен 🙂

    • Может быть кто-то наталкивался на готовое решение для CI

      Честно говоря не сталкивался. Можно поискать на CIForge.
      А вообще этот функционал сильно напоминает CMS.

      • а такое облако тегов можно поставить в партнерский магазин, который парсит товары?

        • Да, можно, но конкретная реализация зависит от того, как сохранены в базе данные о товарах.

  • Так, а будет ли это облако тегов лучше чем обычный модуль для вордпресс? Будет ли он таким же функциональным, но более шустрым?

    • Анфиса,

      Это не модуль для WordPress, а отдельное решение для CodeIgniter 🙂

    • Что бы этим решение было удобно использовать в WP его нужно переделать в виде плагина к WP и с учетом ее структуры базы данных.
      Т.е. в конечном итоге получится очередной плагин. Будет работать он быстрее или нет — зависит от вас 🙂

  • Так, а будет ли это облако тегов лучше чем обычный модуль для вордпресс? Будет ли он таким же функциональным, но более шустрым?

    • Анфиса,

      Это не модуль для WordPress, а отдельное решение для CodeIgniter 🙂

    • Что бы этим решение было удобно использовать в WP его нужно переделать в виде плагина к WP и с учетом ее структуры базы данных.
      Т.е. в конечном итоге получится очередной плагин. Будет работать он быстрее или нет — зависит от вас 🙂

  • Надо на вордпрессе попробовать, а то никак для блога не могу норм прикрутить облако, сколько уже плагинов пробовал

  • Надо на вордпрессе попробовать, а то никак для блога не могу норм прикрутить облако, сколько уже плагинов пробовал

  • Хорошая статья, спасибо. Получил недавно задание сделать облако, а что это такое и не знал. Но у менятакой вопрос: А зачем оно собственно нужно, это облако? Я предполагал что это как-то в раскрутке помогает, хотя вряд ли так уж сильно. Или им действительно пользователи пользуются?

    • Обычно облако используется вместо (или как дополнение) перечня разделов сайта. Часто в разделах информация группируется по темам сообщений, а в облаке — по ключевым словам, но по-большому счету это одно и то же.
      Пользователи пользуются 🙂 Зачастую в блогах это единственный способ навигации.
      В раскрутке оно помогает не больше чем любой другой навигационный блок.

      • Спасибо, Владимир. Сам блогами не пользуюсь, поэтому как то не сталкивался. А когда обнаруживал подобное «облачко», оно меня всегда несколько смущало. Теперь понятно. В общем на нормальном сайте с продуманной структурой это не особбенно нужно.

      • таааак…что то вы кажеться не верно говорите…я не специалист в сео, но облако тегов как раз лучше индексируется и как раз по ключевикам, поэтому работает намного лучше чем блок навигации (так мне обьяснили специалисты и это одна из причин по которой я хочу установить такое облачко себе на сайт)

        • Я не сравнивал. Но часто в облаке тегов оказывается очень много ключевиков (и часть из них закрывают от пользователей с помощью JS). Может в этом причина лучшей индексации?

  • Хорошая статья, спасибо. Получил недавно задание сделать облако, а что это такое и не знал. Но у менятакой вопрос: А зачем оно собственно нужно, это облако? Я предполагал что это как-то в раскрутке помогает, хотя вряд ли так уж сильно. Или им действительно пользователи пользуются?

    • Обычно облако используется вместо (или как дополнение) перечня разделов сайта. Часто в разделах информация группируется по темам сообщений, а в облаке — по ключевым словам, но по-большому счету это одно и то же.
      Пользователи пользуются 🙂 Зачастую в блогах это единственный способ навигации.
      В раскрутке оно помогает не больше чем любой другой навигационный блок.

      • Спасибо, Владимир. Сам блогами не пользуюсь, поэтому как то не сталкивался. А когда обнаруживал подобное «облачко», оно меня всегда несколько смущало. Теперь понятно. В общем на нормальном сайте с продуманной структурой это не особбенно нужно.

      • таааак…что то вы кажеться не верно говорите…я не специалист в сео, но облако тегов как раз лучше индексируется и как раз по ключевикам, поэтому работает намного лучше чем блок навигации (так мне обьяснили специалисты и это одна из причин по которой я хочу установить такое облачко себе на сайт)

        • Я не сравнивал. Но часто в облаке тегов оказывается очень много ключевиков (и часть из них закрывают от пользователей с помощью JS). Может в этом причина лучшей индексации?

  • Олег

    Спасибо за подробную статью. Поддержу позицию автора: дублирование записей в БД рекомендуется делать через дополнительную таблицу. Но соглашусь, что оба варианта будут работать.

    В статье описан случай хранения, частично вывода (с этим нет сложностей) и вывода облака.
    Есть встречный вопрос, как сделать так?
    http://www.google.com/webhp?complete=1&hl=en
    Такое применяется сейчас в социалке вконтакте.
    Т.е. чтобы при начале набора тега, появлялись варианты ответов.
    Но здесь тоже сложности. Через запятую внося ключевые слова, теоретически уже не получится показывать варианты существующих тегов.

    • Есть видеоурок на эту тему http://video.derekallard.com/video/downloads

      И, честно говоря, я не до конца понял вопрос о тегах.
      Автодополнение реализуется с помощью ajax. Т.е. с помощью javascript анализируем введенный текст и отправляем запрос серверу, который должен вернуть список с вариантами. В простейшем случае можно сразу отправить весь введенный текст, но ничто не мешает сделать предварительную обработку, например, вырезать начало строки включая последнюю запятую. По-хорошему, конечно, нужно обеспечить подсказки не только для последнего тега. Т.е. определить положение курсора, вырезать текущий тег (по запятым) и отправить его серверу.

      Примерно такой вариант реализован на bobrdobr.ru, правда иногда подглючивает (или просто притормаживает).

      • Олег

        пример:
        статья_1
        вводятся теги: яблоко, груша, слива, смородина

        статья_2
        вводятся теги: яблокИ, смородина, вишня, клубника

        как вносятся теги в табличку tags и как они разносятся в табличку posts_tags.
        что делать со смородиной? 🙂

        tags

        id tag
        1 яблоко
        2 груша
        3 слива
        4 смородина
        5 яблокИ
        6 смородина
        7 вишня
        8 клубника

        • Смородина в таблице tags должна быть только одна.
          В таблице posts_tags будет две записи для смородины.
          Например,

          posts_tags

          id postid tagid
          1 5 4
          2 6 4

          где 5, 6 — id статьи 1 и статьи 2 в таблице posts.

          Естественно, перед добавлением тега нужно проверить существует ли он уже в базе.

  • Олег

    Спасибо за подробную статью. Поддержу позицию автора: дублирование записей в БД рекомендуется делать через дополнительную таблицу. Но соглашусь, что оба варианта будут работать.

    В статье описан случай хранения, частично вывода (с этим нет сложностей) и вывода облака.
    Есть встречный вопрос, как сделать так?
    http://www.google.com/webhp?complete=1&hl=en
    Такое применяется сейчас в социалке вконтакте.
    Т.е. чтобы при начале набора тега, появлялись варианты ответов.
    Но здесь тоже сложности. Через запятую внося ключевые слова, теоретически уже не получится показывать варианты существующих тегов.

    • Есть видеоурок на эту тему http://video.derekallard.com/video/downloads

      И, честно говоря, я не до конца понял вопрос о тегах.
      Автодополнение реализуется с помощью ajax. Т.е. с помощью javascript анализируем введенный текст и отправляем запрос серверу, который должен вернуть список с вариантами. В простейшем случае можно сразу отправить весь введенный текст, но ничто не мешает сделать предварительную обработку, например, вырезать начало строки включая последнюю запятую. По-хорошему, конечно, нужно обеспечить подсказки не только для последнего тега. Т.е. определить положение курсора, вырезать текущий тег (по запятым) и отправить его серверу.

      Примерно такой вариант реализован на bobrdobr.ru, правда иногда подглючивает (или просто притормаживает).

      • Олег

        пример:
        статья_1
        вводятся теги: яблоко, груша, слива, смородина

        статья_2
        вводятся теги: яблокИ, смородина, вишня, клубника

        как вносятся теги в табличку tags и как они разносятся в табличку posts_tags.
        что делать со смородиной? 🙂

        tags

        id tag
        1 яблоко
        2 груша
        3 слива
        4 смородина
        5 яблокИ
        6 смородина
        7 вишня
        8 клубника

        • Смородина в таблице tags должна быть только одна.
          В таблице posts_tags будет две записи для смородины.
          Например,

          posts_tags

          id postid tagid
          1 5 4
          2 6 4

          где 5, 6 — id статьи 1 и статьи 2 в таблице posts.

          Естественно, перед добавлением тега нужно проверить существует ли он уже в базе.

  • интересно, я но подошел когда прочтению к слову база сразу отпало интересное. Суть в чем. нужно сделать строчку скажем как мета тего ключевых слов в заголовке, после чего должен быть скрипт который беря данные с этой строчки, по-разному каждый раз, строил облако тегов. Зачем? Для поисковой оптимизации.

    • По разному — это значит с разными якорями ссылок?
      Тогда ничего сложного, добавляем еще одну таблицу, в которой перечисляем варианты одного и того же тега. Получится что-то вроде:
      id — первичный ключ
      tagId — id основного тега в таблице tags
      altTagName — альтернативный тег

      После этого получаем все записи из этой таблицы, которые имеют один и тот же tagId, а затем выбираем случайным образом какой-то один.

  • интересно, я но подошел когда прочтению к слову база сразу отпало интересное. Суть в чем. нужно сделать строчку скажем как мета тего ключевых слов в заголовке, после чего должен быть скрипт который беря данные с этой строчки, по-разному каждый раз, строил облако тегов. Зачем? Для поисковой оптимизации.

    • По разному — это значит с разными якорями ссылок?
      Тогда ничего сложного, добавляем еще одну таблицу, в которой перечисляем варианты одного и того же тега. Получится что-то вроде:
      id — первичный ключ
      tagId — id основного тега в таблице tags
      altTagName — альтернативный тег

      После этого получаем все записи из этой таблицы, которые имеют один и тот же tagId, а затем выбираем случайным образом какой-то один.

  • Олег

    Возникла сложность с внесением тегов в табличку.
    Поле tag в таблице tags у нас UNIQUE.

    Поля postID и TagID у нас UNIQUE в таблице post_tags.
    Вносим массив тэгов, которые пользователь внес:
    INSERT INTO tags (tag) VALUES ('$tags[$i]')
    $tags_id = mysql_insert_id();

    но при внесении в post_tags возникают сложности:
    INSERT INTO post_tags (postID, TagID) VALUES ('$post_ID', '$tags_id')
    в таблице имеем:
    9 1
    10 2
    10 10
    11 0
    11 11

    как мне узнать id тега, который уже есть в таблице tags, чтобы его внести в таблицу post_tags?

    • >> как мне узнать id тега, который уже есть в таблице tags

      SELECT id FROM tags WHERE tag='$tags[i]'

      если запрос вернет id, то используем его, если получим пустой результат, то значит тега в таблице tags нет, тогда выполняем

      INSERT INTO tags (tag) VALUES ('$tags[$i]')

  • Олег

    Возникла сложность с внесением тегов в табличку.
    Поле tag в таблице tags у нас UNIQUE.

    Поля postID и TagID у нас UNIQUE в таблице post_tags.
    Вносим массив тэгов, которые пользователь внес:
    INSERT INTO tags (tag) VALUES ('$tags[$i]')
    $tags_id = mysql_insert_id();

    но при внесении в post_tags возникают сложности:
    INSERT INTO post_tags (postID, TagID) VALUES ('$post_ID', '$tags_id')
    в таблице имеем:
    9 1
    10 2
    10 10
    11 0
    11 11

    как мне узнать id тега, который уже есть в таблице tags, чтобы его внести в таблицу post_tags?

    • >> как мне узнать id тега, который уже есть в таблице tags

      SELECT id FROM tags WHERE tag='$tags[i]'

      если запрос вернет id, то используем его, если получим пустой результат, то значит тега в таблице tags нет, тогда выполняем

      INSERT INTO tags (tag) VALUES ('$tags[$i]')

  • Олег

    спасибо за помощь!

  • Олег

    спасибо за помощь!

  • Вывод тегов не универсально организован. Если будет присутствовать один тег, количество вхождений которого будет значительно превышать остальные, то оформление станет кривым: один тег будет большим, а все остальные примерно одинакового размера. Сам статью писал недавно по этому вопросу здесь : http://i-novice.net/oblako-tegov/
    Проблема решается простеньким алгоритмом кластеризации. Ссылки на его реализацию можно там в комментариях к статье посмотреть.

    • Огромное спасибо за ссылку!
      Как-то раньше я не задумывался об этой проблеме. Точнее с проблемой я сталкивался (в основном на сервисах закладок), но о том как ее решить почему-то не думал. Наверное работал стереотип: если минимальный размер шрифта будет нормально читаться, а максимальный — не будет очень большим, то все отлично.
      Нужно будет попробовать реализовать что-то подобное, идея в общем-то не простая.

  • Вывод тегов не универсально организован. Если будет присутствовать один тег, количество вхождений которого будет значительно превышать остальные, то оформление станет кривым: один тег будет большим, а все остальные примерно одинакового размера. Сам статью писал недавно по этому вопросу здесь : http://i-novice.net/oblako-tegov/
    Проблема решается простеньким алгоритмом кластеризации. Ссылки на его реализацию можно там в комментариях к статье посмотреть.

    • Огромное спасибо за ссылку!
      Как-то раньше я не задумывался об этой проблеме. Точнее с проблемой я сталкивался (в основном на сервисах закладок), но о том как ее решить почему-то не думал. Наверное работал стереотип: если минимальный размер шрифта будет нормально читаться, а максимальный — не будет очень большим, то все отлично.
      Нужно будет попробовать реализовать что-то подобное, идея в общем-то не простая.

  • Хороший пример! Если еще так же подробно распишете как создать для САЙТА двужущееся облако тегов — цены вам не будет!

    • Для движущегося облака тегов видел готовую реализацию на флеше, есть даже плагин для WordPress.
      Только вот на мой взляд пользоваться им не очень удобно, теги которые оказываются на заднем плане получаются очень мелкими. Кроме того, если тегов много удобнее искать когда они упорядочены (по алфавиту). И опять же, непонятно как такое облако будет проиндексировано поисковиками. Скорее всего, никак.
      Но выглядит безусловно очень красиво 😉

      • Давно хотел спросить: Вы не пробовали реализовать такую штуку для CI ?

        Вы не совсем правы, относительно удобства-неудобства. Это ведь, по сути, очень зрелищная «игрушка». Задний план «читать» вовсе даже не требуется, подведи указатель и ссылка сама к тебе «приедет» 🙂 У меня такой стоял на WP-блоге, так я сам минут по десять, при каждом посещении, его с удовольствием «вертел» :). Фон для страницы и флэшки брал одного цвета, а теги контрастного из цветовой палитры темы. Красиво и полезно…

        Нам ведь нужно задержать посетителя? Вот и пусть «поиграется» Все равно кончится «кликом»… Вот бы кто-нить такую забаву к Google adSense прикрутил :)…???

      • Критерии «удобства» и «полезности» слишком не однозначны в определении, что очень хорошо продемонстрировано в мультике про «дядю Федора»: «… а какая польза от этой картины, например? Очень даже большая! Она дырку на обоях закрывает!…» 🙂
        Так вращающийся клубок тегов во Флэше для CI можно сделать?

        • Можно, конечно. Облако будет тем же самым (т.е. флешка та же самая), нужно его только подключить к CI.

          Я как-то писал пост о подключении графиков, сделанных на флеше. Тут принцип будет тот же: подключить готовый флеш ролик, передать ему параметры.
          Но, т.к. я сам с флешем не работал, то без инструкции от разработчика флешки не сделаю.

          А вообще идея хорошая, спасибо 🙂

        • Ну, вот, сделал человек «3D Culumus» облако тегов Прекрасно работает и очень эффектно выглядит http://6log.ru/page/sm_cumulus Скажем человеку большое спасибо

        • Согласен.

  • Хороший пример! Если еще так же подробно распишете как создать для САЙТА двужущееся облако тегов — цены вам не будет!

    • Для движущегося облака тегов видел готовую реализацию на флеше, есть даже плагин для WordPress.
      Только вот на мой взляд пользоваться им не очень удобно, теги которые оказываются на заднем плане получаются очень мелкими. Кроме того, если тегов много удобнее искать когда они упорядочены (по алфавиту). И опять же, непонятно как такое облако будет проиндексировано поисковиками. Скорее всего, никак.
      Но выглядит безусловно очень красиво 😉

      • Давно хотел спросить: Вы не пробовали реализовать такую штуку для CI ?

        Вы не совсем правы, относительно удобства-неудобства. Это ведь, по сути, очень зрелищная «игрушка». Задний план «читать» вовсе даже не требуется, подведи указатель и ссылка сама к тебе «приедет» 🙂 У меня такой стоял на WP-блоге, так я сам минут по десять, при каждом посещении, его с удовольствием «вертел» :). Фон для страницы и флэшки брал одного цвета, а теги контрастного из цветовой палитры темы. Красиво и полезно…

        Нам ведь нужно задержать посетителя? Вот и пусть «поиграется» Все равно кончится «кликом»… Вот бы кто-нить такую забаву к Google adSense прикрутил :)…???

      • Критерии «удобства» и «полезности» слишком не однозначны в определении, что очень хорошо продемонстрировано в мультике про «дядю Федора»: «… а какая польза от этой картины, например? Очень даже большая! Она дырку на обоях закрывает!…» 🙂
        Так вращающийся клубок тегов во Флэше для CI можно сделать?

        • Можно, конечно. Облако будет тем же самым (т.е. флешка та же самая), нужно его только подключить к CI.

          Я как-то писал пост о подключении графиков, сделанных на флеше. Тут принцип будет тот же: подключить готовый флеш ролик, передать ему параметры.
          Но, т.к. я сам с флешем не работал, то без инструкции от разработчика флешки не сделаю.

          А вообще идея хорошая, спасибо 🙂

        • Ну, вот, сделал человек «3D Culumus» облако тегов Прекрасно работает и очень эффектно выглядит http://6log.ru/page/sm_cumulus Скажем человеку большое спасибо

        • Согласен.

  • Pingback: Как выбрать себе Ассемблер? Некоторые рекомендации новичку! « Блог для Программистов()

  • Big_Shark

    По мне так вариант Макса по лучше и по удобнее будет)
    Чего ты так на оптимизацию базы накинулись? Юзайте кэш и будет вам счастья)

    Значит если статья уже имеет 5 тегов и я хочу добавить еще 1, то сначала будут удалены 5 записей из БД, а затем вставлены новые 6? Выглядит немного неэкономно, но с другой стороны всего 2 запроса…

    Эта веть в админки и делаеть пару раз в день а не каждые 5 минут ) так что ничего страшного!

    • Я согласен, вариант Максима, наверное, более универсальный.

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

      Эта веть в админки и делаеть пару раз в день а не каждые 5 минут

      А если речь идет не о блоге, а о сервисе социальных закладок?

      P.S. Я ни на кого не накидывался, просто обсуждали 🙂

      • Big_Shark

        Ну в сервисе соц закладок я думаю серваки могут позволить себе по 2 запроса на добовления ) ктомуже это серогно делаеться в любом случае реже чем пользователь ходит по сайту обновляя страницы

        Кэш сейчас должен быть на любом сайте без него не куда.
        Я уже даже если привожу примеры каких то скриптов своих то там всегда включен мой клас кеша по умолчанию и пописано кеширования для всего что работает с БД

        P.S. Я не только про тебя я про всех) все так решили сыкономить 0.005 секунд на запроси что проста жуть)

        • Кэш сейчас должен быть на любом сайте

          Не согласен, это зависит от нагрузки на сайт. При 10 юниках в сутки кэш однозначно не даст никакого эффекта 😉 .

          0.005 сек это, конечно, не много. Но запрос тут, запрос там, а в результате дополнительные 20, 30, … % нагрузки на сервер.

          Но вообще нужно считать, что дешевле: арендовать более мощный сервер или заниматься оптимизацией приложения.

        • Big_Shark

          при 10 юниках в сутки и об оптимизации сайта слишком задумываться не стоит)
          20 запросов эта не реально многа если больше 10 на страницу нужно задуматься о кеши и оптимизации даже не то что задуматься а все срочно перевести на кэш)

        • я имел ввиду, что нагрузка может увеличится на 20% из-за нескольких дополнительных запросов.

          Честно говоря, сложно даже придумать как использовать 20 запросов для одной страницы. Разве что если в сайдбаре куча виджетов.

        • Big_Shark

          Как практика показывает обычна 1 запрос отнимает время а все остальное выполняет очень быстро.
          Сложна придумать даже 10 запросов!
          Хотя я видел скрипт где было 1630 запросов)
          Запросы шли в циклах) После полу часа работы все свялось к 3 запросам в кеш)

        • 1630 запросов

          no comments 🙂

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

          1 запрос отнимает время а все остальное выполняет очень быстро

          создание соединения с БД в первом запросе перед выборкой данных

        • Big_Shark

          Хорошо что сервак не упал при 10000 запросов!)

        • Какой сервак? 🙂
          Все на локалхосте работало 🙂 . Это меня попросили игрушку помочь перевести. Все тексты были в базе (SQLight), их нужно было перегнать в текстовый файл, который пропускался через переводчик, а затем результат нужно было загнать обратно в базу.
          В общем, скрипт отрабатывал дольше чем я его писал 🙂 .

  • Big_Shark

    По мне так вариант Макса по лучше и по удобнее будет)
    Чего ты так на оптимизацию базы накинулись? Юзайте кэш и будет вам счастья)

    Значит если статья уже имеет 5 тегов и я хочу добавить еще 1, то сначала будут удалены 5 записей из БД, а затем вставлены новые 6? Выглядит немного неэкономно, но с другой стороны всего 2 запроса…

    Эта веть в админки и делаеть пару раз в день а не каждые 5 минут ) так что ничего страшного!

    • Я согласен, вариант Максима, наверное, более универсальный.

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

      Эта веть в админки и делаеть пару раз в день а не каждые 5 минут

      А если речь идет не о блоге, а о сервисе социальных закладок?

      P.S. Я ни на кого не накидывался, просто обсуждали 🙂

      • Big_Shark

        Ну в сервисе соц закладок я думаю серваки могут позволить себе по 2 запроса на добовления ) ктомуже это серогно делаеться в любом случае реже чем пользователь ходит по сайту обновляя страницы

        Кэш сейчас должен быть на любом сайте без него не куда.
        Я уже даже если привожу примеры каких то скриптов своих то там всегда включен мой клас кеша по умолчанию и пописано кеширования для всего что работает с БД

        P.S. Я не только про тебя я про всех) все так решили сыкономить 0.005 секунд на запроси что проста жуть)

        • Кэш сейчас должен быть на любом сайте

          Не согласен, это зависит от нагрузки на сайт. При 10 юниках в сутки кэш однозначно не даст никакого эффекта 😉 .

          0.005 сек это, конечно, не много. Но запрос тут, запрос там, а в результате дополнительные 20, 30, … % нагрузки на сервер.

          Но вообще нужно считать, что дешевле: арендовать более мощный сервер или заниматься оптимизацией приложения.

        • Big_Shark

          при 10 юниках в сутки и об оптимизации сайта слишком задумываться не стоит)
          20 запросов эта не реально многа если больше 10 на страницу нужно задуматься о кеши и оптимизации даже не то что задуматься а все срочно перевести на кэш)

        • я имел ввиду, что нагрузка может увеличится на 20% из-за нескольких дополнительных запросов.

          Честно говоря, сложно даже придумать как использовать 20 запросов для одной страницы. Разве что если в сайдбаре куча виджетов.

        • Big_Shark

          Как практика показывает обычна 1 запрос отнимает время а все остальное выполняет очень быстро.
          Сложна придумать даже 10 запросов!
          Хотя я видел скрипт где было 1630 запросов)
          Запросы шли в циклах) После полу часа работы все свялось к 3 запросам в кеш)

        • 1630 запросов

          no comments 🙂

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

          1 запрос отнимает время а все остальное выполняет очень быстро

          создание соединения с БД в первом запросе перед выборкой данных

        • Big_Shark

          Хорошо что сервак не упал при 10000 запросов!)

        • Какой сервак? 🙂
          Все на локалхосте работало 🙂 . Это меня попросили игрушку помочь перевести. Все тексты были в базе (SQLight), их нужно было перегнать в текстовый файл, который пропускался через переводчик, а затем результат нужно было загнать обратно в базу.
          В общем, скрипт отрабатывал дольше чем я его писал 🙂 .

  • Все что вы тут писали для меня полный бред, так как я не програламер 🙂 но хочу иметь на своей доски объявлений облако тегов. В моем понимании это должно выглядеть так:

    Устанавливается php скрипт который собирает статистику потом ее обрабатывает и при помощи инклуда выводит в нужное мне место. Просто и со вкусом, без всяких бла бла бла.

    Желательно, чтоб такой скрипт развивали, были обновления и всякие завороты. Думаю, идея проста.

    • Какой смысл статистику собирать? Вся нужная информация для создания облака есть в базе сразу же после публикации поста.
      А если нужно просто облако, то во многих движках есть встроенные функции, которые его создают (или есть соответствующие плагины).

  • Все что вы тут писали для меня полный бред, так как я не програламер 🙂 но хочу иметь на своей доски объявлений облако тегов. В моем понимании это должно выглядеть так:

    Устанавливается php скрипт который собирает статистику потом ее обрабатывает и при помощи инклуда выводит в нужное мне место. Просто и со вкусом, без всяких бла бла бла.

    Желательно, чтоб такой скрипт развивали, были обновления и всякие завороты. Думаю, идея проста.

    • Какой смысл статистику собирать? Вся нужная информация для создания облака есть в базе сразу же после публикации поста.
      А если нужно просто облако, то во многих движках есть встроенные функции, которые его создают (или есть соответствующие плагины).

  • А существуют ли какие-нибудь автоматические русские облака???

    • А что значит русские? С поддержкой кириллицы?
      Это не проблема на сегодняшний день. Если движок сайта (например, тот же WordPress) нормально работает с кириллицей, то и проблем с облаком не будет.

  • А существуют ли какие-нибудь автоматические русские облака???

    • А что значит русские? С поддержкой кириллицы?
      Это не проблема на сегодняшний день. Если движок сайта (например, тот же WordPress) нормально работает с кириллицей, то и проблем с облаком не будет.

  • Роман

    извините за нубский вопрос, но я не понял в чем выигрыш?
    1000 постов например просмотреть добавленную ячейку с перечислением тегов через разделитель(пусть их 30) это 1000 операций
    а просмотреть вашу связующую таблицу 1000 постов * 30 тегов *3 (пусть в среднем используется 3 тега) это почти 100 000 запросов
    разница кратна 100!!!
    или я что то не так понял?

    • Дело в том, что операции выполняются разное время.
      Если теги будут записаны в одной строке через разделитель, то в запросе придется использовать условие Like. Если теги сохранены каждый отдельно, то они просто сравниваются (равны/не равны).
      Для того, чтобы лучше понять проблему попробуйте написать две функции (только без использования встроенных функций для работы со строками):
      1) сравнивает две строки и возвращает true если строки равны, false — если не равны;
      2) ищет указанный тег в строке с несколькими тегами, разделенными запятыми, возвращает true — если тег найден. (напоминаю, функции вроде explode не используете).

      Кроме того, 1000 постов * 30 тегов *3 — это не количество запросов, это количество записей в таблице POSTS_TAGS. Запрос только один. Данные в этой таблице MySQL имеют тип INT, т.е. поиск по ним будет выполняться значительно быстрее, чем по строкам.

      Если будут ещё вопросы, или получатся непонятные результаты, пишите, попробую помочь 😉

      • Вы ошибаетесь насчет тегов, записанных через разделитель. Не нужно никаких LIKE, это все можно легко сделать на пхп, разделив теги explode() и занести их в массив =)
        Вот моя статья про облако тегов на php (codeigniter) http://ezhik-v-dele.ru/blog/note/27-Oblako-Tegov

  • Роман

    извините за нубский вопрос, но я не понял в чем выигрыш?
    1000 постов например просмотреть добавленную ячейку с перечислением тегов через разделитель(пусть их 30) это 1000 операций
    а просмотреть вашу связующую таблицу 1000 постов * 30 тегов *3 (пусть в среднем используется 3 тега) это почти 100 000 запросов
    разница кратна 100!!!
    или я что то не так понял?

    • Дело в том, что операции выполняются разное время.
      Если теги будут записаны в одной строке через разделитель, то в запросе придется использовать условие Like. Если теги сохранены каждый отдельно, то они просто сравниваются (равны/не равны).
      Для того, чтобы лучше понять проблему попробуйте написать две функции (только без использования встроенных функций для работы со строками):
      1) сравнивает две строки и возвращает true если строки равны, false — если не равны;
      2) ищет указанный тег в строке с несколькими тегами, разделенными запятыми, возвращает true — если тег найден. (напоминаю, функции вроде explode не используете).

      Кроме того, 1000 постов * 30 тегов *3 — это не количество запросов, это количество записей в таблице POSTS_TAGS. Запрос только один. Данные в этой таблице MySQL имеют тип INT, т.е. поиск по ним будет выполняться значительно быстрее, чем по строкам.

      Если будут ещё вопросы, или получатся непонятные результаты, пишите, попробую помочь 😉

      • Вы ошибаетесь насчет тегов, записанных через разделитель. Не нужно никаких LIKE, это все можно легко сделать на пхп, разделив теги explode() и занести их в массив =)
        Вот моя статья про облако тегов на php (codeigniter) http://ezhik-v-dele.ru/blog/note/27-Oblako-Tegov

  • Хорошая статья, НО:
    Для тех, кто все же желает обойтись без использования дополнительной таблицы в БД и соответственно ключей, а тупо писать теги через запятую для каждой записи могу посоветовать мою идею : http://ezhik-v-dele.ru/blog/note/27-Oblako-Tegov
    Используется на нашем сайте (кстате тоже на CodeIgniter), среднее время, затраченное на исполнение алгоритма : 0.0014 с (это при порядка 400 тегах на 100 записей блога.)

    • Не спорю, так сделать можно, но тогда нужно идти дальше 🙂
      А зачем вообще БД? Если мы её возможностями не пользуемся. Хранить записи и теги можно в обычных файлах (или файле). Ведь при использовании вашего алгоритма вы все-равно должны получить все записи из базы, а потом разбирать теги с помощью PHP.

      Не подумайте, я вас не критикую. Вам нужно было облако тегов, вы его сделали и результат вас устраивает — это главное.
      Но поиск — одна из самых сильных сторон реляционных БД и есть смысл им пользоваться.

  • Хорошая статья, НО:
    Для тех, кто все же желает обойтись без использования дополнительной таблицы в БД и соответственно ключей, а тупо писать теги через запятую для каждой записи могу посоветовать мою идею : http://ezhik-v-dele.ru/blog/note/27-Oblako-Tegov
    Используется на нашем сайте (кстате тоже на CodeIgniter), среднее время, затраченное на исполнение алгоритма : 0.0014 с (это при порядка 400 тегах на 100 записей блога.)

    • Не спорю, так сделать можно, но тогда нужно идти дальше 🙂
      А зачем вообще БД? Если мы её возможностями не пользуемся. Хранить записи и теги можно в обычных файлах (или файле). Ведь при использовании вашего алгоритма вы все-равно должны получить все записи из базы, а потом разбирать теги с помощью PHP.

      Не подумайте, я вас не критикую. Вам нужно было облако тегов, вы его сделали и результат вас устраивает — это главное.
      Но поиск — одна из самых сильных сторон реляционных БД и есть смысл им пользоваться.

  • Владимир, а где продолжение статьи?
    Чтобы реализовать ссылки и связь ил с полями в таблице с постами.

  • Владимир, а где продолжение статьи?
    Чтобы реализовать ссылки и связь ил с полями в таблице с постами.

  • Petrik

    Я как сделать, если при добавлении поста, новости и т.д., в строку через запятую вводить тэги, добавлять в БД, но если совпадения, не предпринимать действий.

    • Убрать одинаковые теги из строки не сложно.
      1) Разбиваете строку на слова. Результат будет в виде массива.
      2) С помощью array_unique убираете дубли из массива.
      3) Сохраняете данные в базу.

  • Petrik

    Я как сделать, если при добавлении поста, новости и т.д., в строку через запятую вводить тэги, добавлять в БД, но если совпадения, не предпринимать действий.

    • Убрать одинаковые теги из строки не сложно.
      1) Разбиваете строку на слова. Результат будет в виде массива.
      2) С помощью array_unique убираете дубли из массива.
      3) Сохраняете данные в базу.

  • nomos

    Это всё конечно хорошо, но меня интересует вопрос «автозавершения» тега, если он есть в базе, то есть поле ввода тегов должно выводить варианты дописания слова при вводе первых букв. Я так понимаю, что это должен быть скрипт поиска вводимого значения среди всех тегов базы, так?

    • Правильно. В статье этого нет, но готовых примеров довольно много, например, этот.

  • nomos

    Это всё конечно хорошо, но меня интересует вопрос «автозавершения» тега, если он есть в базе, то есть поле ввода тегов должно выводить варианты дописания слова при вводе первых букв. Я так понимаю, что это должен быть скрипт поиска вводимого значения среди всех тегов базы, так?

    • Правильно. В статье этого нет, но готовых примеров довольно много, например, этот.

  • Юрий

    ну добавлять метки в таблицу TAG например можно, а как реализовать таблицу posts_tags, чтобы добавить значения.
    И последний главный вопрос…
    Как вывести эти метки в посте.

    • Давайте уточним, какие метки имеются ввиду? Мета данные о которых говорил MAX? Если да, то использовать таблицу posts_tags в этом случае не нужно. У вас будет 2 таблицы: posts и meta, а отношение между ними — один-к-многим.
      Т.е. в таблице meta нужно создать поле post_id, которое будет использоваться в качестве внешнего ключа (в это поле записывается id поста к которому относится запись в таблице meta).
      Чтобы найти все мета данные, которые относятся к заданному посту, нужно выполнить запрос вроде
      SELECT * FROM meta WHERE post_id=123

  • Юрий

    ну добавлять метки в таблицу TAG например можно, а как реализовать таблицу posts_tags, чтобы добавить значения.
    И последний главный вопрос…
    Как вывести эти метки в посте.

    • Давайте уточним, какие метки имеются ввиду? Мета данные о которых говорил MAX? Если да, то использовать таблицу posts_tags в этом случае не нужно. У вас будет 2 таблицы: posts и meta, а отношение между ними — один-к-многим.
      Т.е. в таблице meta нужно создать поле post_id, которое будет использоваться в качестве внешнего ключа (в это поле записывается id поста к которому относится запись в таблице meta).
      Чтобы найти все мета данные, которые относятся к заданному посту, нужно выполнить запрос вроде
      SELECT * FROM meta WHERE post_id=123

  • Очень познавательная статья. Хоть у меня стоит плагин, однако прочитал с интересом, хочу сделать сайт и надеюсь пригодиться.

  • Очень познавательная статья. Хоть у меня стоит плагин, однако прочитал с интересом, хочу сделать сайт и надеюсь пригодиться.

  • Roman

    шутки по поводу «трудно придумать 10 запросов» не понял
    вот обычный минус тегов через сводную таблицу
    — вывод названий списком с указанием тегов в подписи
    если у вас 10 названий на страницу еще норм
    а 50? а 100? вот вам и 100 запросов

    • В принципе, в отдельных случаях, никто не запрещает применять денормализацию БД. Т.е. в таблицу с названиями добавить поле теги и перечислить их через запятую. Я понимаю, что это дублирование данных и возможны очень неприятные последствия 😉 , но это реальная возможность убрать ваши 100 запросов.
      Или использовать, если возможно, кеширование.

  • Roman

    шутки по поводу «трудно придумать 10 запросов» не понял
    вот обычный минус тегов через сводную таблицу
    — вывод названий списком с указанием тегов в подписи
    если у вас 10 названий на страницу еще норм
    а 50? а 100? вот вам и 100 запросов

    • В принципе, в отдельных случаях, никто не запрещает применять денормализацию БД. Т.е. в таблицу с названиями добавить поле теги и перечислить их через запятую. Я понимаю, что это дублирование данных и возможны очень неприятные последствия 😉 , но это реальная возможность убрать ваши 100 запросов.
      Или использовать, если возможно, кеширование.

  • nomos

    Для ДЛЕ я пользовался хаком, но в целом принцип тот же, в скрипте держим все теги для автозавершения, а в базе ведём уникальные теги и количество совпадений, и в зависимости от количества уже размер шрифта например…)

  • nomos

    Для ДЛЕ я пользовался хаком, но в целом принцип тот же, в скрипте держим все теги для автозавершения, а в базе ведём уникальные теги и количество совпадений, и в зависимости от количества уже размер шрифта например…)

  • Brdm

    А почему бы не сделать облако тегов на файловой базе?Все очень просто. В каждой строке пишется тег, а через разделитель перечень ссылок на страницы сайта или блога.
    Задача скрипта сформировать только анонсы страниц принадлежащих данному кронкретному тегу в строке базы. Это можно встретить в CMS_ках без баз типа http://acvarif.net.ru/ и ей подобных. Если пишется свой собственный скрипт, думаю такой вариант вполне может подойти.

  • По-большому счету, облако в любом случае хранится в файлах, т.к. все данные БД хранятся именно в них 😉
    Использовать файлы напрямую имеет смысл если вы не используете БД вообще. А комбинирование файлов и БД в данном случае приведет к дублированию данных.

  • caferman

    Спасибо за неплохое решение)

  • Adds

    Как все это дело реализовать, на самописанном сайте?

  • Создание облака — точно также. Т.е. метод getTagCloudData и структура базы отличаться не будут (если, конечно, вы не захотите их изменить).

    Разница будет в выводе облака на страницы сайта. getTagCloudData возвращает массив с данными, а вам нужно будет сформировать html разметку.

  • Adds

    база у меня как показано на примере в начале. дело в том что у меня естественно нету файла (database), на сколько я понимаю, если будет этот файл отсутствовать, то многие запросы не пройдут, правильно я понял?

  • О каком файле database речь? database.php? В нем находятся только параметры подключения к БД. У вас должен быть свой файл с этими настройками (либо вы указали их прямо в основном скрипте).

    В любом случае, если вы можете подключиться к своей базе, то у вас есть все, что нужно 😉

  • Adds

    ну файл есть подключ. к базе bd.php. а на самописанном файле будет работать классы?

  • Adds

    т.е. на самописанном сайте, извиняюсь за свою невнимательность.

  • Adds

    Владимир, помогите реализовать этот скрипт. у меня на сайте классы не работают. есть альтернативный вариант?

  • Классы будут работать независимо от того самописный движок или нет.

  • Но какие-то сообщения об ошибках появляются?

  • Adds

    я сделал все так как показано на вверху, но ничего не выводится…сплошные ошибки тока. файл tagcloud.php выдает вот эту ошибку (Parse error: syntax error, unexpected T_STRING in W:homeengells.comwwwtagcloud.php on line 22)

    а файл tagcloudmodel.php (Fatal error: Class 'Model' not found in W:homeengells.comwwwtagcloudmodel.php on line 6)

    что все это значит?

  • Adds

    Да. в чем может быть причина?

  • Adds

    да, в чем может быть причина?

  • Судя по описанию ошибок, вы пытаетесь использовать файлы контроллера
    без фреймворка.

    Если в объявлении класса написано

    class TagCloudModel extends Model

    то это означает, что класс TagCloudModel является потомком класса
    Model и PHP должен этот класс найти. Вы CodeIgniter не используете и
    поэтому у вас этого класса нет.

    В вашем случае нужно взять из этого класса только метод
    getTagCloudData (можно объявить его обычной функцией), который
    отправляет запрос для получения данных облака.

    В getTagCloudData нужно будет заменить вызов
    $this->db->query($qGetCloud);
    чем-то вроде
    mysql_query($qGetCloud);
    (я не знаю, используете ли вы какие-нибудь библиотеки для работы с БД).

    3 сентября 2010 г. 23:46 пользователь Disqus
    <> написал:

  • Adds

    <В вашем случае нужно взять из этого класса только метод

    getTagCloudData (можно объявить его обычной функцией), который

    отправляет запрос для получения данных облака.>

    А как объявить класс, подскажите? я не чайник в php

  • class ClassName {
    //методы класса
    }

    Сам класс может находится в этом же php скрипте или в отдельном. В последнем случае, перед использованием класса скрипт нужно будет подключить с помощью include или require.

    • Adds

      Реализовал этот скрипт на сайте. теперь другой вопрос: статьи добавляются через админку, хотел реализовать при добавление статьи, чтобы можно было выбрать тег… подскажите пожалуйста как это дело реализовать правильно???????

      • 1) Получить список тегов из базы.
        2) Сформировать список (select) или группу чекбоксов (если можно выбирать сразу несколько кодировок).
        3) При сохранении статьи в БД добавлять записи в таблицу posts_tags для каждого выбранного тега.

        • Adds

          выводить список тегов не проблема. дело в том что я не могу записать id в табличке posts_tags так как пока не знаю каким будет id пока не добавлю заметку в базу… есть выход из ситуации???

        • После добавления поста в базу (запрос insert) можно сразу же получить его первичный ключ (id).
          Если вы используете функции mysql, то вам нужна mysql_insert_id.
          Во всех распространенных библиотеках и фреймворках есть аналогичные функции.

  • Roma

    Помогите решить такую проблему:
    Для запроса я использую mysql_query, и у меня вибирается 1 елемент из бд. Проблема втом что у вас формируется масив уже со всеми тегами а я не знаю как так сделать (.

    Статья супер, спасибо!

    • Какой запрос вы выполняете в mysql_query?
      Мой запрос написан в листинге 2 (строки 7-9).

  • Аноним

    как можно сделать облоко тегов без Java Skript?

    • Если я ничего не путаю, в этой статье JS не используется 🙂

  • Ozze

    Прошу прощения, если уже писалось, но мб лучше …FROM posts_tags LEFT INNER tags ON… ? Тогда в результате будут только те tag.id, которые хоть раз соответствуют tagid. Зачем нам отображать теги, к которым ничего не привязано? Чтобы запутать пользователя?)) Вроде ничего не напутал.

    • Как лучше — решать вам 🙂
      Если не нужно показывать пустые теги — используйте INNER JOIN, если хотите вывести все — LEFT OUTER.

  • Ozze

    INNER JOIN

  • Roosso

    Привет.
    Как то не подружился я с Вашей математикой. =) Характерми не сошлись.
    И вот родил свою.

    $fontsize = round(((($maxsize-$minsize)/$max)*$cntposts)+$minsize);

    Вроде изящнее вышло.
    Так же задал и минимум и максимум.

    • >> Как то не подружился я с Вашей математикой

      Не страшно 🙂 Главное чтобы размер шрифта был правильный 🙂

      • В целом, меня просто запутала по недосыпу формула в вашем примере. =) Поэтому я пошел простым математическим способом. Рассчитал шаг =) Размер везде правильный пока что. =)

  • Qwerty

    Хуйня

  • Александр

    Спасибо, Очень интересная статья.

    Сейчас делаю что то похожее и столкнулся с проблемой:Допустим у нас есть на странице вывод сотни статей и у каждой статьи есть по несколько тэгов (тэги естественно ссылки). Какой в таком случае будет оптимальный запрос к базе данных. Сейчас временно это сделано таким образом что сначала мы выбираем список статей и потом в цекле дляя каждой статьи сбираем ее тэги. Понимаю что реализация не верная потому как получается огромное количество запросов, но другой пока не придумал.

    • Основных вариантов 2.

      Первый — ваш. Основной недостаток вы сами поняли — большое количество запросов. Но, дело в том, что запросы бывают разные. И скорость их выполнения может отличаться в сотни и тысячи раз. Поэтому делать вывод просто на основании количества запросов — не правильно.
      Преимуществом данного подхода является минимальное количество потребляемой памяти. Вся нужная информация вытягивается только один раз.

      Второй вариант — использовать 1 запрос с объединениями (JOIN).
      Для примера из этой статьи запрос может выглядеть так

      SELECT posts.*, tags.tag FROM posts LEFT JOIN posts_tags ON posts.id=posts_tags.postid
          LEFT JOIN tags ON posts_tags.tagid=tags.id

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

      Есть еще комбинированный вариант. Использовать запрос из второго примера, но вытягивать не все данные поста, а только его id. Затем в цикле пройтись по всем id и получить полные данные постов. Т.е. получится N+1 запрос, где N — количество постов на странице.

      В любом случае, желательно попробовать несколько вариантов и сравнить время выполнения запросов и потребление памяти.

      Только не забывайте, что результат зависит и от количества тегов, и от объема постов. Если у вас во время тестирования будут тексты постов по 2-3 слова, а на рабочем сайте редактор будет писать статьи по 5-10 кБ, то результат тестирования может получиться немного не адекватным 😉

      • Александр

        Второй вариант с использованием JOIN мне не нравится по причине того что кол-во строк в результирующей таблице будет всегда разным в зависимости от кол-ва тегов каждой статьи. И мы не сможем с помощью LIMIT «отрезать» нужное количество строк.

        По ходу решения задачи появилась еще одна мысль. Выполнить 2 запроса:
        1. Выбираем все необходимые посты
        2. Выбираем только id постов и тэги которые им соответствуют. В итоге получаем тибличку впроде этойid   tagId   tag Title
        1      2           php
        1      3           java
        2      1           css
        2      4           html

        Затем перебираем все посты и для каждого соответствующего id присваеваем ему необходимые теги. При кол-ве 100 постов на странице и в среднем 3 тега на пост получим 30000 итераций. Хотя можно уменьшить это число удаляя из массива уже использованные тэги.

        Что Вы думаете о таком решении?

        • Можно сформировать нужный массив с тегами в один проход.
          Идея заключается в создании ассоциативного массива ключами в котором будут id постов. Т.е. примерно так (исходные данные в массиве $tags).

          $tags_by_posts = array();
          foreach ($tags as $tag) {
              $tags_by_posts[ $tag['id'] ] = array($tag['tagId'], $tag['tagTitle']);
          }

          Дальше, думаю, понятно. Чтобы получить теги какого-нибудь поста — просто выбираем нужный элемент массива.
          $cur_post_tags = $tags_by_posts[ $cur_post_id ];

  • Sdfsd

    [url=http://vakansivahtovik.blogspot.com/]Отличный пост,спасибочки,подсказали мне)[/url]

  • Max

    Я тоже строю баню.Вот моя банька
    http://vse-probani.ru/index.php/banya-svoimi-rukami

  • CandyDandy

    Приятно видеть урок на CodeIgniter ))

  • Berik91_20

    как сделат облако тег

  • роман

    http://jromka.ru/read/23 вот еще неплохое описание

  • Андрей

    Спасибо, за урок. Вот здесь не плохо выполнено облако! креативперсон.рф

  • Маша

    скажите а как это можно связать с html? А то я делаю сайт, и мне б хотелось туда добавить облако. Помогите прошу

    • Я не против помочь вам, но напишите подробнее в чем именно проблема.

      Код , который приведён в статье, создаёт HTML разметку. Он будет отображаться на любой html странице. Просто выведите его там где вы хотите разместить облако.

  • Михаил

    Спасибо. Оч. нужно было понять принцип.

  • Александер

    А допустим, верстаю сайт на html и вручную вписываю теги в код страниц. Как правильно писать, чтобы все работало?

    • Просто на HTML вы облако тегов не создадите, т.к. не сможете получить данные из базы и обработать их.