Вопрос собственно к WRC. Ты ведь написал своё двигло под блог, скажи, как ты реализовал отлов повторных просмотров для постов? Я думаю сделать отдельную базу и вести учет айпишников. Хватит ли этого? Бесплатные обои.
как ты реализовал отлов повторных просмотров для постов?
Собственно 2 решения я написал в своём блоге. Больше я ничего не придумал... у себя я в начале поставил отлов с помощью куков, но совершенно случайно обнаружил что в осле и опере это почему то не канает (я лазаю в мозилке)... и поэтому недавно поменял на сессии - хоть и не совершенно точно, но кроссбраузерно.
Quote (Aleko)
Я думаю сделать отдельную базу и вести учет айпишников.
Базу всего лишь для этого? бред... я даже для меню пожадничал базы... И потом... просмотры это то, чего может быть очень много. Больше всего остального... Лучше узнать как ограничить время жизни определённой сессии, а не всех как делает функция session_set_cookie_params() (перечитал весь нет, ничего стоищего не нашёл) Ну а если такого не возможно то валяй... делай базу айпишников. Этого вполне хватит, но задолбаешься делать... Устраняем баг при просмотре материала
Да нет, базу сделать просто. У меня сейчас около 20 сложно связанных таблиц и нормально, всё летает - главное не тупить с проектированием базы а делать по уму. Другое дело что лишние запросы это плохо. Сессиями я делать не хочу так как накрутить будет легко - сессия держится пока не закроется окно браузера, затем только кука висит, которую можно легко стереть. По этому и нужна база. Ты кстати используешь сессионные куки или свои вешаешь, например при входе на сайт? Бесплатные обои.
<? function movies_stats_add($id){ if(!preg_match("/^\d+$/",$id)){return false;} if(isset($_SESSION['movies_stats_'.$id])){return false;} $_SESSION['movies_stats_'.$id]=''; require_once("sql.php"); mysql_query("UPDATE movies SET hosts=hosts+1 WHERE id=".$id); return true; }
echo movies_stats_add(1); ?>
Логика такова что просмотром считается открытие страницы материала в течении одной сессии. То есть если вы просмотрели новость, потом закрыли браузер, снова его открыли и ещё раз просмотрели новость то к новости прибавится соответственно 2 запроса, я считаю такие запросы "легальными". В итоге не нужно пасти ip адрес и ронять базу раз в сутки - полный дзен.
Дабы зря не грузить сервак сначала я проверяю $id материала, затем проверяю, не просматривал ли пользователь эту новость в течение текущей сессии и только потом подрубаюсь к базе, вешаю сессию и увеличиваю значение хостов на 1.
главное не тупить с проектированием базы а делать по уму.
Вот у меня была такая ошибка. Хотел как бы всё по быстрее сделать и сказать алилуя... А теперь каждый раз переписываю скрипт.
Quote (Aleko)
сессия держится пока не закроется окно браузера
Цитирую с сайта где я "учусь":
Quote
session_set_cookie_params(int lifetime [, string path [, string domain]]) - с помощью этой функции можно установить, как долго будет "жить" сессия, задав unix_timestamp определяющий время "смерти" сессии. По умолчанию, сессия "живёт" до тех пор, пока клиент не закроет окно браузера.
То есть если верить этому определению можно сменить метод сбрасывания сессии: закрытие браузера на время.
Quote (Aleko)
Ты кстати используешь сессионные куки или свои вешаешь, например при входе на сайт?
И расскажи ка мне что такое сессионные куки и свои вешалки, а то я знаю только сессии и куки
Quote (Aleko)
я сделал так:
Ну дак ведь моё решение на сессиях имеет такой же смысл.
Code
<?php session_start(); if(!$_SESSION['movies_stats_'.$id]){ require_once("sql.php"); mysql_query("UPDATE movies SET hosts=hosts+1 WHERE id=".$id); $_SESSION['movies_stats_'.$id] = 1; } ?>
Но проблема всё ещё остаётся. Этим методом так же можно набить просмотры, правда закрытием и открытием браузера Устраняем баг при просмотре материала
Сессии это те же самые куки. Прочитай про механизм сессий. Их жизнь обычно гарантируется до закрытия окна + несколько часов (в зависимости от настройки php.ini), именно поэтому я так и написал. Во время авторизации я вешаю свою куку дабы после перезагрузки компа пользователь не вводил логин и пароль заного. Могу выложить листинг моей авторзации. Бесплатные обои.
Сессии это те же самые куки. Прочитай про механизм сессий.
Это я знаю. Вообще сессии произошли от куков.
Quote (Aleko)
Их жизнь обычно гарантируется до закрытия окна + несколько часов (в зависимости от настройки php.ini), именно поэтому я так и написал.
То есть ты намекаешь что сессия обрабатываются в браузере? А для чего тогда path? Вполне логично было бы сохранять туда сессии. Ну лично я так думаю, без всяких умных текстов
Quote (Aleko)
Во время авторизации я вешаю свою куку дабы после перезагрузки компа пользователь не вводил логин и пароль заного. Могу выложить листинг моей авторзации.
Нет. Не нужно. Я уже подозреваю какая у тебя там форма. Я что то подобное задумал для добавления комментов. А вот интересно, как на ucoz сделаны просмотры. Есть идеи? Всё таки на ucoz можно набивать просмотры, но очень очень постепенно. Допустим эту тему, я, в дальнейшем, раз десять уже посмотрел. Сейчас посмотрел и просмотр всё равно увеличился. Значит используется не база данных, а что то другое. Хотя не факт что их система работает на php. Устраняем баг при просмотре материала
Очень просто. За хост считается уникальный ip. При просмотре новости с уникального ip он пишется в sql базу вместе с id материала. После чего материалу плюсуется хост. Раз в сутки или около того сервер дропает базу ip адресов и хосты зачисляются по новой. Я практически уверен что всё именно так, отличие может быть в том что отлавливается не только ip но ещё скажем разрешение экрана - так обычно делают. почитай по запросам "подсчет хостов". Бесплатные обои.
А я так не думаю. Я проверил во всех браузерах, и во всех на одну единицу хост повысился. Мож всё таки с браузером мутят? Ну ip уж точно отпадает. Ну если только они в базу ещё тип браузера забивают, тогда уж пусь, но зачем? Устраняем баг при просмотре материала
Лады... от дискуссий к делу. Я всё таки поменял своё отношение к базам, после того как придумал, как их можно легко удалять. Но всё же количество запросов резко увеличилось:
//избавляемся от просроченных эелементов mysql_query('DELETE FROM views WHERE delite_time<'.time());
//добавляем хост и элемент в views если в нём нет соответствующего элемента $views_result = mysql_query('SELECT * FROM views WHERE ip="'.$_SERVER['REMOTE_ADDR'].'" AND post_id='.$id); if(!$views_result){//не уверен что такое условие выдаст то что нужно но пусь пока так mysql_query('UPDATE blog SET reads=reads+1 WHERE id='.$id); mysql_query('INSERT INTO views (ip, post_id, delite_time) VALUES ("'.$_SERVER['REMOTE_ADDR'].'", '.$id.', '.(time()+86400).')'); //...+24 часа } ?>
WRC, в mysql есть механизм событий - можно повесить выполнение определенного запроса раз в 24 часа к примеру. )) читай гугл - я только так и живу. Бесплатные обои.
$views_result в твоем случае кстати всегда будет true. False будет только в том случае если с базой данных "физически" не удалось связаться. Нужно проверять так: mysql_rows_affected($views_result)!=0 Бесплатные обои.
<?php if (!$_SESSION['pbs'.$post['id']]) { mysql_query('UPDATE sd_posts SET post_view_count="'.($post['post_view_count']+1).'"WHERE id="'.$post['id'].'"'); $_SESSION['pbs'.$post['id']]=1; } ?>
Проверял локально работает нормально. Количество просмотров зачисляется таким мпособом: открыл браузер, просмотрел +1 к просмотру. Открыл с др. браузера тоже +1. Закрыл браузер открыл данный пост +1 к просмотрам.
Все варианты сходятся к одному. Думаю эта проблема решена. Меня волнует другае теперь проблема. Капча.. Я ща делаю капчу на основе kcapcha. У вас я вижу свои капчи. На какой основе они? Большие фотостатусы
Всё просто... работать нужно с сессиями... с начало разберись с самим кодом (смысле тот случайный код что будет на картинке), а потом уже приступай к картинке... Скоро напишу пост в блоге про капчу: php + js)
Это для mssql - другая программа) я юзаю mysql, как и ты)
Вот код моей капчи:
Code
<?
// Возвращает изображение с проверочным кодом и создает у текущего пользователя // сессионную переменную captcha с его копией. $width = 80; // Ширина изображения $height = 36; // Высота изображения $font_size = 11; // Размер шрифта $let_amount = 5; // Количество символов, которые нужно набрать $font = "captcha.ttf"; //Путь к шрифту $letters = array('2','3','4','5','6','7','8','9','A','a','w','v','B','C','D','E','F','G','H','K','L','M','N','P','R','S','T','U','X','Y','Z'); // используемые символы $colors = array("10","40","70","100","130","160","190"); // используемые цвета $linesnum = 4; // количество линий на изображении $dotsnum = 100; // количество точек на изображении
Вешаем сессию с кодоп капчи, посылаем форму с ней же пользователю и ждем ответа. Сверяем код возвратившийся от пользователя и код в сессии, если всё ок - идем дальше.
Aleko, ты ещё хотел написать код авторизации. Я примерно понимаю как это.. Но все же хочется взглянуть на готовую. Просто у меня будет админка и нужно к ней закрыть доступ
Ещё вопрос ты как ЧПУ делал? Все прописывал через .htaccess или передаешь параметры .htaccess с помошью php?
Aleko, спасибо за капчу Юзаю Но я тебе ещё посоветую очищать сесию капчи, после каждого ввода кода безопасности, не важно корректный он или нет. Большие фотостатусы
Важно очищать сессию после каждой проверки (неважно, успешной или нет). Не стоит полагаться на то, что при обновлении страницы скрипт картинки сгенерит новый текст — бот может просто не запрашивать картинку, а вводить один и тот же ответ, который в самом начале прочитал и сообщил боту сам злоумышленник.
Ну я со словом "резко" немного преувеличил) Сам посмотри как главная грузится и страница материала... Вроде страница немного медленнее, или это просто изо того что я так хочу думать. Показалось видать. Сделал так:
Code
mysql_query('DELETE FROM views WHERE delite_time<'.time()); $views_result = mysql_query('SELECT * FROM views WHERE ip="'.$_SERVER['REMOTE_ADDR'].'" AND post_id='.$full['id']); if(!mysql_result($views_result,0)){ mysql_query('UPDATE blog SET reads=reads+1 WHERE id="'.$full['id'].'"'); mysql_query('INSERT INTO views (ip, post_id, delite_time) VALUES ("'.$_SERVER['REMOTE_ADDR'].'", '.$full['id'].', '.(time()+86400).')'); }
WRC, ну во первых http://www.mysql.ru/docs/man/UNION.html почитай, пригодится, во вторых ты проверяешь старые записи каждый раз а мог бы раз в час хотя бы. В итоге будет 2 запроса вместо четырех:
Code
if(mysql_result(mysql_query("SELECT COUNT(*) FROM views WHERE ip='$_SERVER[REMOTE_ADDR]' AND post_id=$full[id]"),0) == 0){ // получаем количество строк mysql_query("begin"); // открываем поток mysql_query("UPDATE blog SET reads=reads+1 WHERE id=$full[id]"); mysql_query("INSERT INTO views (ip, post_id, delite_time) VALUES ('$_SERVER[REMOTE_ADDR]',$full[id],".(time()+86400).")"); mysql_query("commit"); // закрываем поток }
Slimmi, это ведь элементарные вещи, которые тебе уже давно должны сразу приходить в голову. Допустим материалы выводятся следующим циклом:
Code
while($date = аррэй(запрос)){ echo 'тратата'; }
Теперь добавим несколько переменных и условие к содержимому в цикле:
Code
$i = 0; $str = $_GET['str'];//с какого материала начинать $numstr = 5;//количество материалов на одной странице while($date = аррэй(запрос)){ $i++;//порядковый номер материала if($i>$str && $i<=($str+$numstr)){ echo 'тратата'; } //вводим в адр. строку index.php?str=5 и материалы будут //высвечиваться с порядковыми номерами от 6 до 10 }