• 88550
  • 417
  • 44
Нравится блог?
Подписывайтесь!

AJAX - Учимся на примерах. Часть 2 - Свое облако тегов.

В сегодняшнем уроке мы попытаемся создать такoе модное и актуальное для web 2.0 решение проблемы навигации, как облако тегов (tag cloud, англ). Что это такое - это визуальное представление списка ярлыков (или категорий). Частота упоминаний, поисков, ссылок в интернете с определенного сайта неких слов, терминов, имен, отображается на специальной странице в виде изображения этих слов в формате гиперссылок. Размер изображения тем больше, чем выше релевантность данного слова (термина, имени). Наглядными примерами могут быть облака тегов на самом yvision.kz (пользователи, теги топиков). Целью урока является создание механизма для работы с тегами, и, соответственно вывода их в виде облака. Инструментами послужат PHP и JavaScript фреймворк JQuery, о котором я писал в прошлом уроке.

Как источник используем данные с самого же yvision-а. 1 - Пользователи, 2 - Сообщества. Облако тегов будет строиться в зависимости от рейтинга пользователя/сообщества.

Разделим работу на 3 этапа:

1. Написание парсера для получения данных сайта

2. Создание механизма кэширования результатов

3. Создание механизма для построения облака тегов

Этап номер 1. Источниками данных послужат 2 страницы - список пользователей и список сообществ.

Напишем небольшую функцию, с использованием CURL для получение HTML-кода интересующей нас страницы. В качестве параметра передается URL-адрес.


function
get_html($url) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
return curl_exec($ch);
curl_close($ch);

}

Для нахождения нужных значений используем уже описанную ранее функцию get_nums():

function get_nums($text, $openingMarker, $closingMarker){
$openingMarkerLength = strlen($openingMarker);
$closingMarkerLength = strlen($closingMarker);
$result = array();
$position = 0;
while (($position = strpos($text, $openingMarker, $position)) !== false) {
$position += $openingMarkerLength;
if (($closingMarkerPosition = strpos($text, $closingMarker, $position)) !== false) {
$result[] = substr($text, $position, $closingMarkerPosition - $position);
$position = $closingMarkerPosition + $closingMarkerLength;
}
}
return $result;

}

Для получения списка пользователей и их рейтинга используем небольшую функцию get_users(), результатом работы которой будет массив со значениями (имя => рейтинг). Поскольку страница пользователей разделена на две части (активные блоггеры, новые блоггеры), мы берем данные только со второй части страницы, чтобы избавиться от лишней работы по удалению дублирующихся результатов.

function get_users(){
$html = get_html('http://yvision.kz/people/');
$data = get_nums($html, 'Новые пользователи</div>', '<div class=bottom>');
$data = substr($data[0], 85, strlen($data[0]) - 118);
$users = get_nums($data, 'bold;"><a class="alogin" href="http://', '.yvision.kz" onfocus');
$rating = get_nums($data, 'jpg"></a><br>', '</div>');
return array_combine($users, $rating);

}

Получение списка сообществ и их рейтинга выглядит похожим образом (функция get_comm()). Примечание: переменная $cmax- это текущее количество страниц с сообществами, на момент написания топика их было 7.

function get_comm(){
$cmax = 7;
for ($i = 1; $i <= $cmax; $i++) {
$html .= get_html('http://yvision.kz/community/' . $i);
}
$names = get_nums($html, 'left;"><a href="http://yvision.kz/community/', '/">');
$data = get_nums($html, '<td class="tmp0">', '</td>');
for($i=2;$i<count($data);){
$rating[] = $data[$i];
$i = $i+3;
}
return array_combine($names, $rating);

}

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

function set_cache($data, $type){
$data = serialize($data);
$fp = fopen($type.'.txt', 'w');
fputs($fp, $data);
fclose($fp);
}

function
get_cache($type){
$fp = file_get_contents($type.'.txt');
return unserialize($fp);

}

В качестве параметра $data передаем массив с тегами, а в качестве параметра $type - тип данных, который соответствует названию функций получения тегов (для пользователей это - get_users, а для сообществ - get_comm).

Этап номер 3. Работа по постороению облака тегов будет выглядеть следующим образом:

1) Пользователь вводит параметры отображения через форму и отправляет запрос

2) Согласно полученным данным, выводится облако тегов в том виде, в котором запросил сам пользователь.

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

Внешний вид нашего облака будет зависить от следующих параметров: мин. порог рейтинга ($minRate), мин. размер шрифта ($minFontSize), макс. размер шрифта($maxFontSize), способ сортировки ($sortType). Для наглядности, цвет текста будет генерироваться случайно ($fcolor). Размер шрифта для каждой отдельной записи определяется в зависимости от текущего и максимального рейтинга ($fsize) в пределах, определенных самим пользователем с помощью логарифмической функции.

$sortType - это способ сортировки результатов. Их будет 3 - без сортировки (ksort), по возрастанию (asort) и по убыванию (arsort). Сортировка массивов проводится соответственными функциями языка PHP.

function show_cloud($tags, $minRate = 1, $minFontSize = 5, $maxFontSize = 30, $sortType='ksort'){
$fontRange = $maxFontSize - $minFontSize;
$maxTagCnt = 0;
$minTagCnt = 1000000;
foreach ($tags as $n => $r) {
if ($r >= $minRate) {
if ($r > $maxTagCnt) $maxTagCnt = $r;
if ($r < $minTagCnt) $minTagCnt = $r;
}
}
$tagCntRange = $maxTagCnt + 1 - $minTagCount;
$minLog = log($minTagCnt);
$maxLog = log($maxTagCnt);
$logRange = $maxLog - $minLog;
if ($maxLog == $minLog) $logRange = 1;
$sortType($tags);
foreach ($tags as $n => $r) {
$fsize = $minFontSize + $fontRange * (log($r) - $minLog) / $logRange;
$fcolor = dechex(rand(0, 255)) . dechex(rand(0, 255)) . dechex(rand(0, 255));
if ($r >= $minRate) {
printf("<nobr><a style=\"font-size:%dpx;color:#%s\" href=\"#\">%s</a></nobr>\n", (int)$fsize, (string)$fcolor, $n);
}
}

}

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

function get_result(){

var cloud_type = document.getElementById("cloud_type").value;
var sort_type = document.getElementById("sort_type").value;
var minrate = document.getElementById("minrate").value;
var minfont = document.getElementById("minfont").value;
var maxfont = document.getElementById("maxfont").value;
var cache = document.getElementById("cache").value;

$.blockUI({ message: '<b>Обработка данных...</b>' });
$.post(
'index.php',
{
cloud_type: ""+cloud_type+"",
sort_type: ""+sort_type+"",
minrate: ""+minrate+"",
minfont: ""+minfont+"",
maxfont: ""+maxfont+"",
cache: ""+cache+""
},
onAjaxSuccess
);
}

function onAjaxSuccess(data){
$("#result")
.html(data)
.animate({height: "show"}, 900);
$.unblockUI();
}

Определим функцию для обработки события при нажатии кнопки:

$('#submit').bind("click", get_result);

На этом работа завершена. Итогом являются два файла - index.html (форма и отображение) и tags.php (основной скрипт по созданию облака тегов), которые вы можете скачать здесь. И, напоследок, несколько скриншотов работы написанного скрипта:

16 июля 2008, 12:40
1651

Загрузка...

Комментарии

Прикольно :) биг спасиб!
eudj1n
0
0
незачто :)

если интересны какие-то определенные темы - предлагайте, напишу.
NeD
0
0
Тоже самое что и в первой части. Почти ничего про JQuery и много php. Только мне показалось, что заголовки этих статей не соответствуют содержанию?
eudj1n
0
0
В 1 части я объяснял про POST запрос через JQuery, тут существенно ничего не изменилось кроме переменных и названия скрипта. Ок, буду расписывать подробней.
NeD
0
0
Вы в заголовке пишите что пост будет про AJAX, а в содержании про сам AjAX 1 строка. Наверно нестоит обманывать пользователей. Попробуйте давать заголовки своим постам исходя из их содержания.
p0is0n
0
0
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
return curl_exec($ch);
curl_close($ch)

Улыбнуло))
eduha
0
0
Хе-хе :)

А еще надо очень осторожно использовать такую конструкцию:
$sortType($tags);
переменная $sortType приходит от пользователя и никак не проверяется. А это может быть серьезной уязвимостью, потому что можно передать название любой функции php.
eudj1n
0
0
здесь показан всего лишь механизм работы, а не готовый набор функций. само-собой, все входные данные нужно проверять.
Да ладно;) признайся - сбыдлокодил:))
p0is0n
0
0
Причем тут эта конструкция?
К курлу - не при чем :)
velero
0
0
расскажите, простому человеку, что это означает на человеческом языке?
eduha
0
0
Мммм.. после оператора return выполнение функции прекращается. А в коде после ретёрна идет закрытие соединения (curl_close($ch)), но выполняться не будет. Впрочем, ресурс все равно будет закрыт, но только после завершения скрипта.
eduha
0
0
Кстати, раз уж пошла речь о jQuery... Можно было бы написать так...

var cloud_type = document.getElementById("cloud_type").value;

var cloud_type = $('#cloud_type').val();
eduha
0
0
Ну и еще если к мелочам придираться... Вместо fopen - fwrite - fclose можно использовать file_put_contents

Оставьте свой комментарий

Спасибо за открытие блога в Yvision.kz! Чтобы убедиться в отсутствии спама, все комментарии новых пользователей проходят премодерацию. Соблюдение правил нашей блог-платформы ускорит ваш переход в категорию надежных пользователей, не нуждающихся в премодерации. Обязательно прочтите наши правила по указанной ссылке: Правила

Также можно нажать Ctrl+Enter

Популярные посты

Что дал Казахстану переход к трехступенчатой судебной системе?

Что дал Казахстану переход к трехступенчатой судебной системе?

С 1 января 2016 года Казахстан перешел на трехступенчатую судебную систему. Данные изменения действуют уже более 8 месяцев, и в данной публикации мы попробуем разобраться, что это дало Казахстану?
RuSnake
24 сент. 2016 / 11:50
  • 12492
  • 3
В октябре 2016 года состоится VII съезд судей Казахстана

В октябре 2016 года состоится VII съезд судей Казахстана

Проведение съездов судей позволяет принимать стратегические решения по вопросам развития судебной системы и способствует укреплению принципов независимости судейского сообщества.
elawkz
23 сент. 2016 / 13:45
  • 10721
  • 0
О законе законов: Замолвите слово о справедливости

О законе законов: Замолвите слово о справедливости

Акимат г. Астаны предлагал собственнику компенсацию...4 тенге 13 тиын за землю. Потолкуем о справедливости?
mirabeisenova
23 сент. 2016 / 16:39
  • 10429
  • 5
Я –живой пример того, что для начала собственного дела не нужны большие деньги

Я –живой пример того, что для начала собственного дела не нужны большие деньги

Сегодня утром ко мне позвонила тетя и сообщила, что хочет открыть свое дело, но не знает с чего начать и не уверена, хватит ли ей первоначального капитала. Вы не представляете, как она удивилась, когд
toskanbayev_a
21 сент. 2016 / 16:45
  • 10027
  • 27
Тохтар Тулешов: Чистосердечное признание. Кто слил в сеть?

Тохтар Тулешов: Чистосердечное признание. Кто слил в сеть?

Ведется расследование в отношении лиц, причастных к распространению снимков чистосердечного признания Тохтара Тулешова в сети...
TangoInHarlem
19 сент. 2016 / 17:25
  • 9451
  • 11
Кызылорда: перезагрузка, или что изменилось за последние несколько лет

Кызылорда: перезагрузка, или что изменилось за последние несколько лет

В преддверии Дня города мы решили вспомнить, как росла и развивалась наша родная Кызылорда в последние годы. Хотим поделиться своей любовью к родному городу с читателями Юви в этой фотоподборке ...
socium_kzo
22 сент. 2016 / 10:09
  • 6646
  • 8
Сватовство в Казахстане или Заберите скорее мою дочь к себе

Сватовство в Казахстане или Заберите скорее мою дочь к себе

Всю мою сознательную жизнь мне приходилось ходить в гости. В гостях неплохо, не спорю. Бесплатная еда и напитки. В особо продвинутых семьях ещё предоставляются услуги Free Wi-Fi. В особо весёлых...
almatinec_92
23 сент. 2016 / 9:33
25 годовщину независимости от колониального гнета Киргизия встретила вот так...

25 годовщину независимости от колониального гнета Киргизия встретила вот так...

Трехлетний Исхак стал звездой киргизских СМИ и соцсетей на прошлой неделе. Его фотография, спящего на улице среди окурков на картонке, вызвала шок в обществе. В принципе это подобное фото можно...
Shpak
20 сент. 2016 / 15:52
Apple – это уже прошлое. XIAOMI тихо стал настоящим и будущим

Apple – это уже прошлое. XIAOMI тихо стал настоящим и будущим

Безусловно мы все относимся с большим уважением с Стив Джобсу. Но его уже больше 5 лет нет с нами. Бессмысленно продолжать фанатеть от продукции Apple...
GALAN
22 сент. 2016 / 23:19
  • 3512
  • 12