• 91349
  • 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
1735

Загрузка...
Loading...

Комментарии

Прикольно :) биг спасиб!
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

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

Узаконенное варварство в стране, принимающей «EPXO». Еще далеко нам до «топ-30 развитых стран»

Узаконенное варварство в стране, принимающей «EPXO». Еще далеко нам до «топ-30 развитых стран»

В продвинутых государствах едва ли поймут, почему в столь развитом, успешном и преуспевающем Казахстане от имени и по заданию властей творятся такие зверства над животными.
openqazaqstan
24 мая 2017 / 12:12
  • 9299
  • 85
Поддержим пенсией жиреющие банки! На что казахстанцам разрешат досрочно тратить свои накопления в ЕНПФ

Поддержим пенсией жиреющие банки! На что казахстанцам разрешат досрочно тратить свои накопления в ЕНПФ

Со стороны ЕНПФ в очередной раз прозвучало крайне неоднозначное заявление, от которого, на наш взгляд, лучше было бы воздержаться.
openqazaqstan
23 мая 2017 / 11:08
  • 9055
  • 31
Что бы ни сделал пешеход – все равно водитель сядет

Что бы ни сделал пешеход – все равно водитель сядет

Вопрос о равной ответственности водителя и пешехода при наезде на последних, только-только начинают обдумывать в высоких кабинетах. Но, пока государственные головы думают, водители продолжают...
Mirogloff
22 мая 2017 / 23:29
  • 4689
  • 32
Алматинские проститутки превращаются в шпионок

Алматинские проститутки превращаются в шпионок

Попасть в притоны на алматинском проспекте Сейфуллина, которых, как бы ни старались полицейские, меньше не становится, теперь можно, только зная явки и пароли.
Mirogloff
19 мая 2017 / 13:25
  • 4406
  • 38
Вырубка деревьев в Алматы под БРТ. Проект уже нанес городу экологический ущерб

Вырубка деревьев в Алматы под БРТ. Проект уже нанес городу экологический ущерб

Как ранее уже сообщалось из-за строительства БРТ в Алматы пострадают значительное количество деревьев. На прошлой неделе вырублены первые вязы и клён, - под расширение проезжей части на улице...
SKYFALL
24 мая 2017 / 17:20
  • 3620
  • 12
Пока полицейские будут прощать, им будут бить и по чести, и по лицу

Пока полицейские будут прощать, им будут бить и по чести, и по лицу

Судья Алмалинского районного суда Куаныш Арипов ломает стереотипы отношения граждан к представителям Фемиды. Напавшему на полицейского экс-сотруднику алматинского акимата он назначил наказание выше...
Mirogloff
24 мая 2017 / 16:41
  • 3113
  • 9
В Алматы доставили чудотворную икону «Умягчение злых сердец»

В Алматы доставили чудотворную икону «Умягчение злых сердец»

Икона "Умягчение злых сердец" несет особые - сакральные, духовные смыслы. Ее намоленность ощущается даже за те секунды, пока прикасаешься губами к образу.
ValentinaVladimirska
20 мая 2017 / 0:09
  • 3270
  • 0
Да-да, я знаю, пора выходить замуж. Есть ли у меня еще время и, пожалуйста, уточните сколько?

Да-да, я знаю, пора выходить замуж. Есть ли у меня еще время и, пожалуйста, уточните сколько?

Итак давайте сразу начистоту. Мне 29. Не замужем, никогда не была, детей нет. В душе я совсем не чувствую этот возраст. Каждый раз когда задумываюсь об этом больше чем на 3 минуты, меня накрывает...
user2017
23 мая 2017 / 10:57
Выйду замуж по расчету. Брак обесценился, пора вновь возвращать ему ценность

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

После череды неудачных романов, статусов "все сложно", ножей в спину, идея "выйти замуж по расчету" посещает все чаще. И мне не стыдно про это говорить.
energo_ulzhan
22 мая 2017 / 17:39
  • 2645
  • 55