негодяй и извращенец (С)
Доброго времени суток!
Есть форма, посетители вводят свои ответы, результаты php-скрипт отправляет на почту админа и заносит в mySQL БД.
Вопрос: возможно ли в ту же БД вместе с прочими результатами записывать ip голосующего? Или хотя бы на почту его сбрасывать? Нужно для мониторинга накруток.
Дисклеймер: не программист ни разу, только начинаю разбираться по мере надобности. Сваять работающую форму удалось, а вот попытка найти пример записывающего ip скрипта результатов не дала. Буду благодарен за помощь.
Есть форма, посетители вводят свои ответы, результаты php-скрипт отправляет на почту админа и заносит в mySQL БД.
Вопрос: возможно ли в ту же БД вместе с прочими результатами записывать ip голосующего? Или хотя бы на почту его сбрасывать? Нужно для мониторинга накруток.
Дисклеймер: не программист ни разу, только начинаю разбираться по мере надобности. Сваять работающую форму удалось, а вот попытка найти пример записывающего ip скрипта результатов не дала. Буду благодарен за помощь.
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
$ip=$_SERVER['HTTP_CLIENT_IP'];
}
elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
}
else {
$ip=$_SERVER['REMOTE_ADDR'];
}
return $ip;
}
Создавай новое пое в таблице и пользуйся на здоровье,)
Но возник еще один вопрос. Пока разбирался с ['REMOTE_ADDR'], обнаружил очень много интересного по массивам, решил, что стоит заодно записывать, откуда пришел юзер и какой у него браузер. Вот тут и пошли баги. IP я сохранял простейшим $ip = $_SERVER['REMOTE_ADDR']; с добавлением парамерта ip в $ip = $_SERVER['REMOTE_ADDR']; В таком варианте все работает. Но стоит добавить еще пару параметров:
$ip = $_SERVER['REMOTE_ADDR'];
$from = $_SERVER['HTTP_REFERER'];
$browser = $_SERVER['HTTP_USER_AGENT'];
И соответственно
$query="INSERT IGNORE INTO ... (...ip, from, browser) VALUES (...'$ip', '$from', '$browser')";
- как форма перестает функционировать. Никаких ошибок не выдает, пишет, что информация принята, но в БД пусто. Что я делаю не так?
Джей Ди, именно поэтому не хочу ставить защиту по айпи - кому надо, все равно обойдут. Информация о том, с каких айпишников отвечали (а также откуда пришли и каким браузером пользуются), вкупе с ответами юзеров вполне может помочь определить накрутки. Имхо, это вернее, чем автоматическая защита по айпи и куки - при условии, что есть желание копаться в результатах вручную, конечно. В данном случае оно есть.
Мохнорыл, спасибо! Эх, в следующий раз буду перезагружать утром дискуссию, сэкономил бы время. А для чего в скрипте 'HTTP_X_FORWARDED_FOR?
HTTP_X_FORWARDED_FOR там для определения IP пользователей, сидящих за неанонимными прокси.
Я бы сначала убедился, что в таблице созданы соответствующие поля.
И ещё. Переменные, которые начинаются с HTTP_, получены PHP из заголовков HTTP-запроса. Эти заголовки явно указываются клиентом и потому могут быть легко подделаны — т.е. в них может быть совершенно произвольная информация, либо они могут отсутствовать вовсе.
Без предварительной обработки их также не следует использовать в SQL-запросе. Очень советую почитать про атаки типа SQL-injection.
По тем же причинам я не рекомендую вообще использовать код Мохнорыл'а: X-Forwarded-For или Client-IP это всего лишь HTTP-заголовки и в них может быть что угодно. Кроме того, они не определены в RFC и совершенно не обязательно, что будут использоваться тем или иным прокси (либо вместо них могут быть совершенно другие с похожим смыслом).
Можно доверять только $_SERVER['REMOTE_ADDR'] — это, по крайней мере, тот IP-адрес, с которого было установлено соединение с сервером.
Насчет атаки спасибо, пока буду придерживаться стандартного массива, т.к. с предварительной обработкой мне пока явно рано разбираться, сначала азы освоить.
Можно ещё попробовать заменить from на `from`. А вообще я не совсем понял — у вас в случае ошибки в SQL-запросе что-нибудь должно происходить?
А вообще я не совсем понял — у вас в случае ошибки в SQL-запросе что-нибудь должно происходить?
Стоит вывод ошибки в случае неудавшегося соединения, пока это все. Не очень представляю, как выводить ошибку в случае некорректной отправки данных.
Вообще структура следующая:
UPD Неверно сохраняется выше строчка с method=post :
<*form action=<?php print(basename($_SERVER["PHP_SELF"]));?> method=post enctype=multipart/form-data>
Ну как бы mysql_query на запросах типа insert возвращает либо true, либо false, если возникла ошибка. А саму ошибку можно получить через mysql_error(). Классический вариант это что-то типа:
На пробу использовал скрипт, который предложил Мохнорыл - та ж фигня, данные идут во все строки таблицы, кроме ip.
Два вопроса: правильно ли я понимаю, что ip должен упоминаться всего три раза: в строке ip = $_SERVER['REMOTE_ADDR']; и $query="INSERT IGNORE INTO ... (...ip, from, browser) VALUES (...'$ip', '$from', '$browser')"; , больше нигде? И какие параметры должны быть у поля в таблице? Пробовал `ip` VARCHAR( 12 ) и `ip` TEXT( 12 ), с и без NOT NULL , остальные параметры не указаны. Может, у меня тут косяк? Уже не знаю, где еще его искать.
Ну если вы так сильно прячете свой код, то я не знаю, где там конкретно ошибка. )
if (isset($_POST['title1'])) {$title1 = $_POST['title1'];}, и таких 40 штук. Все остальное без изменений. Вот целиком, как сейчас выглядит: narod.ru/disk/17749286000/form.txt.html
В тело сообщения не лезет, слишком длинно.
Отчаялся найти ошибку, написал заново. Работает. Со всеми тремя параметрами, полученными через $_SERVER. В чем была ошибка, буду разбираться после того, как запущу страницу, очень любопытно это выяснить, но хочется уже запустить форму в работу. С ней остался один глюк: после отправки данных загружается снова та же страница. Echo или print исправно выводится после отправки, но под ним сразу же выводится и форма ввода, а это лишнее. Подсказанное поиском <*input type="hidden" name="redirect" value="http://..."> почему-то напрочь игнорируется. Не подскажете?
И в любом случае большое спасибо за вашу помощь!
Вообще когда много копипаста — это не есть хорошо.
Например, однотипные конструкции типа if (isset($_post['smth'])) $var = $_post['smth']; лучше оформить в виде функции:
Код сразу сократится до $var = post_var('smth');
Во-вторых, раз имена параметров имеют номер, можно использовать цикл:
Как нетрудно догадаться, можно аналогичным циклом составить сразу SQL-код. Причём, использовать для этого кучу переменных опять же не требуется.
Точно так же циклом можно выводить сам HTML.
В-третьих, если прямо в HTML записать имена параметров, как title[1], title[2] и т.д., то PHP их преобразует в массив $title с соответствующими ключами.
А страница и должна та же самая загружаться. Если хотите перейти на другую - до вывода какого-либо HTML можно вызвать header('Location: http://www.google.com/'); или, если нужно просто скрыть форму на той же странице, — сделать проверку, отправлены ли данные формы (хотя бы через isset()) и если да, то записать в базу и не показывать форму, или, если нет, — просто показать форму.