Получение уникального количества посещений в php - PullRequest
4 голосов
/ 18 января 2012

Я хочу добавить уникальный счетчик посещений на мой сайт, используя PHP. Этот счетчик сохранит IP-адрес посетителя для каждой страницы в базе данных. У меня есть структура базы данных, как это:

Таблица hits с двумя столбцами:

ip
page_url

Мой вопрос: после получения IP-адреса посетителя в файле PHP, что лучше (для производительности)?

  1. Чтобы проверить, есть ли IP-адрес в базе данных. И когда его еще нет в базе, добавьте его
  2. Просто добавьте все IP-адреса посетителей (без проверки дубликатов), а затем получите разные IP-адреса для соответствующей страницы, чтобы получить уникальный счетчик посещений?

Ответы [ 5 ]

6 голосов
/ 18 января 2012

Если вы используете MySQL, вы можете использовать комбинацию PRIMARY KEY и ON DUPLICATE KEY UPDATE:

CREATE TABLE hits (
ip VARCHAR(15),
page_url VARCHAR(200),
PRIMARY KEY (ip,page_url),
hitcount INT NOT NULL DEFAULT 0
)

Теперь на странице вы нажали

INSERT INTO hits(ip, page_url,hitcount) VALUES('$ip','$url',1)
ON DUPLICATE KEY UPDATE hitcount=hitcount+1

Почему это?

  • Другим уникальным ключом является ЯД для таблицы с интенсивной записью, поэтому избегайте ее. На самом деле.
  • INSERT ... ON DUPLICATE KEY UPDATE блокирует строку только один раз

Вы также можете записать отметку времени последнего доступа:

ALTER TABLE hits ADD COLUMN lastseen TIMESTAMP();
2 голосов
/ 26 апреля 2015

с помощью Eugen Rieck Я сделал свой код с указанием даты и времени.

В этом коде хранятся ip, количество, дата и время пользователя.

$ipaddress = '';
    if (getenv('HTTP_CLIENT_IP'))
        $ipaddress = getenv('HTTP_CLIENT_IP');
    else if(getenv('HTTP_X_FORWARDED_FOR'))
        $ipaddress = getenv('HTTP_X_FORWARDED_FOR');
    else if(getenv('HTTP_X_FORWARDED'))
        $ipaddress = getenv('HTTP_X_FORWARDED');
    else if(getenv('HTTP_FORWARDED_FOR'))
        $ipaddress = getenv('HTTP_FORWARDED_FOR');
    else if(getenv('HTTP_FORWARDED'))
        $ipaddress = getenv('HTTP_FORWARDED');
    else if(getenv('REMOTE_ADDR'))
        $ipaddress = getenv('REMOTE_ADDR');
    else
$ipaddress = 'UNKNOWN'; // final ip address
$time=date("Y/m/d H:i:s"); // date and time in a single variable
$sql = "INSERT IGNORE INTO `ipaddress` (`id`, `ipaddress`, `count`, `time`) VALUES ('', '$ipaddress','1', '$time') ON DUPLICATE KEY UPDATE count=count+1, time='".$time."'"; // adding ip,count, date and time to table
if($conn->query($sql) === false) {
  trigger_error('Wrong SQL: ' . $sql . ' Error: ' . $conn->error, E_USER_ERROR);
} else {

  $last_inserted_id = $conn->insert_id;
  $affected_rows = $conn->affected_rows;
}

$conn->close();
2 голосов
/ 18 января 2012

Предполагая, что вы удобны с простым программированием.

НЕ ИСТИННО «РЕАЛЬНОЕ ВРЕМЯ», НО ПОЧТИ РЕАЛЬНОЕ ВРЕМЯ Настоятельно рекомендую записывать в журнал собственный формат текстового файла (если вам не нравится Apache [customlog][1] особенность).

Затем установите cronjob каждые 5 минут или даже раз в 1 минуту, если вы хотите приблизиться к «live», импортируйте текст во временную таблицу MySql большим глотком с помощью LOAD DATA INFILE и затем обновитеВаша таблица посещений на основе GROUP BY ip.

ПОЛНОСТЬЮ РЕАЛЬНОЕ ВРЕМЯ Это может сильно затянуть ваш сервер, но, учитывая, что у вас небольшой трафик, просто создайте две таблицы в MySQL.Один просто записывает читаемый идентификатор статьи / страницы + IP + время (таблица журнала).Другой содержит идентификатор статьи / страницы и счетчик посещений - там, где обновляется счетчик GROUP BY ip в первой таблице.

1 голос
/ 18 января 2012

Я бы использовал уникальный ключ на (ip, page_url), опционально date. Если запись не существует, она будет создана, в противном случае это приведет к ошибке (но вы можете легко проверить код ошибки) или вы можете использовать IGNORE в INSERT операторе ..

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

0 голосов
/ 28 августа 2013

Привет, Джон, и коллеги подсмотрели поток ... Я новичок в программировании и MYSQL, ... однако, как я обошел его, было следующее:

Я использую некоторый PHP-код для запроса попаданийDB и затем оцените оба столбца, ip и page_url, и если они оцениваются как true, ничего не делают, иначе ... вставьте / выполните код, показанный выше Евгением Риком ...

$ip = $_SERVER['REMOTE_ADDR']; // Get IP Address.

$purl = htmlspecialchars($_GET['page_url']); // Get Page URL.

$results = $mysqli->query("select * from hits"); // Query hits table.

$row = $results->fetch_assoc(); // Fetch array and assign to $row, then evaluate with if statement.

if ($row['ip'] == $ip && $row['page_url'] == $purl) {

} else {
    $mysqli->query("insert into hits (ip,page_url,counter) values ('$ip','$purl',1) on duplicate key update counter=counter+1");
}

Я буду честен, я не проверял это на более чем одном IP-адресе, только мой.

Однако он добавляет строки в таблицу совпадений для каждого вставленного URL-адреса на основе уникального IP-адреса (который я сейчас использую) и не увеличивает счетчик обращений для любого вставленного URL-адреса при обновлении страницы, поэтому яПредположим, это работает ...

...