[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Запись в БД.
vegasmoscow
Пытаюсь разобраться с PHP и MySQL на примере написания простого счетчика посещений. Копировать чужой код и вставлять его в страницу я уже научился, а теперь хочу понять как все это работает smile.gif
Вопрос следующий: я получаю IP адрес посетителя, далее мне нужно проверить, имеется ли такой IP в БД или нет, то есть мне нужно сравнить имеющийся IP с уже записанными в БД. Как это сделать и с чего начинать даже понять не пойму.. sad.gif



Спустя 3 минуты, 25 секунд (22.07.2009 - 20:35) kirik написал(а):
Цитата (vegasmoscow @ 22.07.2009 - 12:31)
Копировать чужой код и вставлять его в страницу я уже научился, а теперь хочу понять как все это работает

Таак smile.gif Твои предположения, алгоритмы, код?

Спустя 21 минута, 6 секунд (22.07.2009 - 20:56) vegasmoscow написал(а):
Алгоритм, собственно, простой, без статистики и т д..

1. Получить IP гостя.
2. Проверить наличие этого IP в базе.
3. Если есть, то остановить скрипт.
4. Если нет, то записать в базу.
5. Увеличить значение счетчика на единицу.

Пока есть только 1 пункт, а на втором я застрял.

Вот код получения IP:

PHP
function get_real_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;
}


ph34r.gif код не мой, здесь пока все сложно для меня sad.gif я имею ввиду все эти ['HTTP_CLIENT_IP'] и ['HTTP_X_FORWARDED_FOR'] всякие..

Спустя 4 минуты, 21 секунда (22.07.2009 - 21:00) kirik написал(а):
Цитата (vegasmoscow @ 22.07.2009 - 12:56)
2. Проверить наличие этого IP в базе.
3. Если есть, то остановить скрипт.
4. Если нет, то записать в базу.
5. Увеличить значение счетчика на единицу.

А какой смысл в этом скрипте? Это все-таки счетчик посещений, или бан всех подряд?

Спустя 4 минуты, 34 секунды (22.07.2009 - 21:05) vegasmoscow написал(а):
Не совсем понял про "бан всех подряд"? Вообще цель научиться пользоваться базой данных хотя бы на таких простеньких примерах, можно начать с текстовых файлов, но, говорят, не по-взрослому это дело smile.gif

Спустя 19 минут, 22 секунды (22.07.2009 - 21:24) kirik написал(а):
Цитата (vegasmoscow @ 22.07.2009 - 13:05)
Не совсем понял про "бан всех подряд"?

Ну смотри, я захожу на сайт первый раз, работает пункт "4. Если нет, то записать в базу.", затем я обновляю страницу, и уже срабатывает пункт "3. Если есть, то остановить скрипт.", тоесть получается бан по IP smile.gif

Спустя 9 минут, 32 секунды (22.07.2009 - 21:34) vegasmoscow написал(а):
Я неправильно выразился, не убивать скрипт die или exit, а просто ничего не записывать в базу, вот и все. Единственный минус, что один IP и через год не повлияет на счетчик (хотя не совсем уверен по поводу динамических IP), но моя то цель пока не в этом.

Спустя 3 минуты, 40 секунд (22.07.2009 - 21:37) kirik написал(а):
Все, теперь ясно smile.gif
Базы данных/таблицы создавать умеешь? Что такое SELECT и WHERE знаешь?

Спустя 5 минут, 33 секунды (22.07.2009 - 21:43) vegasmoscow написал(а):
В данный момент мучаю такую штуку:

PHP
$query=mysql_query("SELECT * FROM `ip`")


Создавать то научился, а вот пользоваться SELECT и WHERE в полной мере нет - не знаю как сформировать запрос правильно, а еще не знаю можно ли сравнить IP адреса в самом запросе или сначала извлечь данные, а потом сравнить .. wacko.gif

Спустя 1 час, 51 секунда (22.07.2009 - 22:44) kirik написал(а):
Цитата (vegasmoscow @ 22.07.2009 - 13:43)
пользоваться SELECT и WHERE в полной мере нет - не знаю как сформировать запрос правильно

Если с английским хорошо, то запрос составить очень просто, возьмем запрос
SQL
SELECT * FROM `table` WHERE `id` = 13

по-русски он будет звучать так:
SQL
ВЫТАЩИТЬ * ИЗ `table` ГДЕ `id` = 13

Тоесть "Вытащить из таблицы `table` все строки и столбцы, где `id` равен 13".

Отсюда плавно вытекает ответ на твой вопрос
Цитата (vegasmoscow @ 22.07.2009 - 13:43)
еще не знаю можно ли сравнить IP адреса в самом запросе или сначала извлечь данные, а потом сравнить

Не нужно извлекать все данные, чтобы сравнить. Можно просто запросить нужные данные, и если они будут в таблице, то вернутся, а если нет, то нет smile.gif

Допустим есть у нас IP - 127.0.0.1, чтобы узнать есть ли он в таблице, сделаем запрос
SQL
SELECT `ip` FROM `ip` WHERE `ip` = '127.0.0.1'

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

Спустя 9 минут, 51 секунда (22.07.2009 - 22:54) vegasmoscow написал(а):
С английским более или менее, но одним английским здесь не отделаешься smile.gif
Что то в этом духе я и предполагал, только никак не могу проверить, что возвращает запрос, как это можно посмотреть через "echo"? Пробовал "mysql_fetch_array" и "mysql_fetch_row", выдает Warning и Notice разные.. что то не так сделал.

Спасибо, что отвечаете!

Спустя 3 часа, 29 минут, 4 секунды (23.07.2009 - 02:23) kirik написал(а):
Цитата (vegasmoscow @ 22.07.2009 - 14:54)
Пробовал "mysql_fetch_array" и "mysql_fetch_row"

Показывай как пробуешь, поправим! smile.gif

Спустя 7 часов, 38 минут, 36 секунд (23.07.2009 - 10:01) mcfly написал(а):
А какая структура БД? Или еще пока не создали? smile.gif

Спустя 4 часа, 40 минут, 49 секунд (23.07.2009 - 14:42) vegasmoscow написал(а):
Структура БД одна колонка для IP адресов и все.

Все, вроде получилось..

PHP
require "db_connect.php";  // подключили БД
require "get_ip.php";  // получили IP гостя

$ip=get_real_ip();

$query=mysql_query("SELECT * FROM `ip` WHERE `list_ip` = '$ip'");  // проверили, есть ли в БД такой же IP

$result=@mysql_result($query, 0);  // получили результат запроса
if (!$result) {  // если результата запроса нет, то...

    $insert=mysql_query("INSERT INTO `ip` VALUES ('$ip')");  // вносим новый IP в БД
        
        
// далее увеличиваем значение счетчика на единицу
        $file="count.txt"; 
        $open_f
=fopen ($file, "r+");  // открыли файл
        flock ($open_f, LOCK_EX);  // заблокировали файл
        $fgc=file_get_contents($file);  // получили содержимое
        $fgc++; // прибавили единицу
        fwrite($open_f, $fgc); // записали новое значение счетчика
        fclose ($open_f); // закрыли файл
}

$file="count.txt";
$fgc_2=file_get_contents($file);
echo ("Страницу посетили ".$fgc_2." пользователей");


Окиньте, плз, своим опытным взглядом сей код, может чего не правильно мыслю?

Есть один нюанс, который мне не понравился, но другого выхода я не нашел - это когда получаю переменную $result , в случае, если такого IP нет в БД, то выскакивает "Warning", который я заглушил собакой. На экране не отображается, но, на сколько я знаю, эти предупреждения и ошибки все равно фиксируются в некий лог файл. корректно ли использование собаки в таком случае?

Спустя 7 минут, 15 секунд (23.07.2009 - 14:49) Nikitian написал(а):
1) Если стоит первичный ключ по полю list_ip, то можно обойтись одним запросом: пытаемся добавить в бд запись и если не добавилась - значит она там уже есть wink.gif
2) Храните ip в int-полях, так бд проще осуществлять поиск и сравнение. Для преобразования строки ip_адреса в число и обратно используются mysql-функции INET_ATON() и INET_NTOA() соответственно.

Спустя 21 минута, 10 секунд (23.07.2009 - 15:10) vegasmoscow написал(а):
1. Первичный это PRIMARY KEY ? Можно переделать, не проблема.

2. А вот если тип поля сделать INT, то записывается только первые цифры адреса до точки, а все остальное игнорируется (но я мог что то напутать в запросе), поэтому я тип поля сделал VARCHAR.

Спустя 1 час, 3 минуты, 24 секунды (23.07.2009 - 16:14) Nikitian написал(а):
Цитата
2. А вот если тип поля сделать INT, то записывается только первые цифры адреса до точки, а все остальное игнорируется (но я мог что то напутать в запросе), поэтому я тип поля сделал VARCHAR.

А для кого было написано это?
Цитата
Для преобразования строки ip_адреса в число и обратно используются mysql-функции INET_ATON() и INET_NTOA() соответственно.

Спустя 1 час, 7 минут, 7 секунд (23.07.2009 - 17:21) vegasmoscow написал(а):
Правильно ли я исправил? Здесь, мне кажется, функция обратного перевода числа в строку INET_NTOA не понадобилась.


Первоначальный фрагмент кода:

PHP
<?php

$query
=mysql_query("SELECT * FROM `ip` WHERE `list_ip` = '$ip'");  // проверили, есть ли в БД такой же IP

$result=@mysql_result($query0);  // получили результат запроса
if (!$result) {  // если результата запроса нет, то...

    
$insert=mysql_query("INSERT INTO `ip` VALUES ('$ip')");  // вносим новый IP в БД



Исправленный фрагмент:

PHP
<?php

$query
=mysql_query("SELECT * FROM `ip` WHERE `list_ip` = INET_ATON('$ip')");  // проверили, есть ли в БД такой же IP

$result=@mysql_result($query0);  // получили результат запроса
if (!$result) {  // если результата запроса нет, то...

    
$insert=mysql_query("INSERT INTO `ip` VALUES (INET_ATON('$ip'))");  // вносим новый IP в БД




Спустя 1 час, 49 минут, 56 секунд (23.07.2009 - 19:11) kirik написал(а):
Цитата (vegasmoscow @ 23.07.2009 - 09:21)
Исправленный фрагмент

Ага, все ОК.
Единственная фишка.. Чтобы не ставить собаку перед mysql_result можно просто проверить пришедшее количество строк через mysql_num_rows(), если больше нуля, значит IP есть.

UPD
А, не.. не единственная smile.gif Там не нужно вытаскивать все значения (звездочка в запросе SELECT). Доставай только те поля, которыми будешь пользоваться. В данном случае это поле `ip`

Спустя 18 минут, 19 секунд (23.07.2009 - 19:29) vegasmoscow написал(а):
По поводу mysql_num_rows(), это вариант, спасибо!

А по поводу звездочки - это я на всякий случай, там все равно одно поле "list_ip" ("ip" это название таблицы). Вроде так..

Спустя 34 минуты, 17 секунд (23.07.2009 - 20:03) kirik написал(а):
Цитата (vegasmoscow @ 23.07.2009 - 11:29)
там все равно одно поле

Ну эт так, на будущее, когда будут таблицы под полсотни полей smile.gif

Спустя 22 минуты, 49 секунд (23.07.2009 - 20:26) vegasmoscow написал(а):
Уххх... blink.gif ..полсотни полей.. wacko.gif я с одним то пока справиться не могу!

Спустя 3 дня, 21 час, 5 минут, 14 секунд (27.07.2009 - 17:32) S{oRpiO написал(а):
Я не понял только одного а зачем число посещений хранить в txt не проще использовать базу(Mysql) ???

Спустя 9 минут, 49 секунд (27.07.2009 - 17:41) S{oRpiO написал(а):
во простенько и со вкусом

PHP
<?
include ("maps/blocks/db.php");
// подключаем файл с соединением с базой
$date = date("d-m-Y в H-i");
//получаем дату и время для учета
$ip = $_SERVER['REMOTE_ADDR'];
//Получаем IP зашедшего
$resylt34 = mysql_query ("SELECT ip FROM info WHERE ip='$ip';",$db);
//Соединяемся с базой и проверяем есть такой ip или нет
$myrow34 = mysql_fetch_array($resylt34);
if ($myrow34 == ""){
// проверяем если в зпрос ничего не попало по поиску ip 
//nj записываем все это дело
$result = mysql_query ("INSERT INTO info (ip,date) VALUES ('$ip','$date')",$db); 
}
$resylt43 = mysql_query ("SELECT visit FROM visit WHERE id='1';",$db);
$myrow43 = mysql_fetch_array($resylt43);
//вытаскиваем значение посещений на данный момент
$visit = $myrow43[0] + 1;
//плюсуем посещения еще на одно
$result44 = mysql_query ("UPDATE visit SET visit='$visit' WHERE id='1'",$db); 
//Записываем в базу новые данные


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

Спустя 2 дня, 4 часа, 19 минут, 26 секунд (29.07.2009 - 22:01) vegasmoscow написал(а):
S{oRpiO,

Цитата (S{oRpiO @ 27.07.2009 - 14:32)
Я не понял только одного а зачем число посещений хранить в txt не проще использовать базу(Mysql) ???


Можно и в БД записывать - не принципиально, цель была научиться на простом примере использовать БД в работе, хотя, признаюсь.. мысль записывать значение счетчика в БД мне не приходила.. sad.gif

Спустя 45 минут, 18 секунд (29.07.2009 - 22:46) sergeiss написал(а):
S{oRpiO - эх ты и понаписал smile.gif
Твои 4 запроса легко и просто упаковываются в 2 запроса.
Первые два:
SQL
INSERT INTO .... ON DUPLICATE KEY UPDATE....

Вставляем данные, а при их существовании делаем просто апдейт

Вторые два... Да то же самое!!!:

SQL
INSERT INTO .... ON DUPLICATE KEY UPDATE....


Соответственно, и меньше будет писанины на ПХП.

Спустя 4 минуты, 34 секунды (29.07.2009 - 22:51) S{oRpiO написал(а):
sergeiss согласен но суть это не меняет да и ког резаный там много чего не хватает это писалось для локалки
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.