[PHP] 방문자 로그 기록 및 방문자수 측정

요즘은 구글 등에서 방문추적 서비스를 제공하고 있기 때문에 방문자 정보를 기록하는 것이 굳이 필요하지는 않지만 클라이언트의 요구가 있어서 간단하게 만들었다. 리퍼러 등의 방문자 접속 정보를 기록하고 일자별 방문자수를 별도 기록해서 관리자 등에서 표시할 때 쉽게 이용할 수 있도록 했다.

각 테이블의 구조는 아래와 같다.

CREATE TABLE `cm_visit` (
  `vi_date` date NOT NULL,
  `vi_count` int(11) UNSIGNED NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE `cm_visit`
  ADD PRIMARY KEY (`vi_date`);

CREATE TABLE `cm_visit_log` (
  `vi_date` date NOT NULL,
  `vi_time` time NOT NULL,
  `vi_referer` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `vi_agent` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `vi_ip` varchar(45) COLLATE utf8mb4_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

ALTER TABLE `cm_visit_log`
  ADD KEY `vi_date` (`vi_date`);

실제로 DB 에 데이터를 기록하는 코드는 아래와 같다.

<?php
function insertVisitLog()
{
    $cm = $GLOBALS['cm'];
    $DB = $GLOBALS['DB'];

    if (!isset($_SESSION['user']['ss_visit_log']) || !$_SESSION['user']['ss_visit_log']) {
        $excludedAgents = array_map('trim', $GLOBALS['excludedAgents']);

        if (empty($excludedAgents) || str_replace($excludedAgents, '', $_SERVER['HTTP_USER_AGENT']) == $_SERVER['HTTP_USER_AGENT']) {
            $sql = " insert into `{$cm['visit_log_table']}` ( vi_date, vi_time, vi_referer, vi_agent, vi_ip ) values ( :vi_date, :vi_time, :vi_referer, :vi_agent, :vi_ip ) ";

            $DB->prepare($sql);
            $DB->bindValueArray([
                ':vi_date'    => CM_TIME_YMD,
                ':vi_time'    => CM_TIME_HIS,
                ':vi_referer' => $_SERVER['HTTP_REFERER'] ? $_SERVER['HTTP_REFERER'] : '',
                ':vi_agent'   => $_SERVER['HTTP_USER_AGENT'],
                ':vi_ip'      => $_SERVER['REMOTE_ADDR']
            ]);

            $result = $DB->execute();

            $_SESSION['user']['ss_visit_log'] = $result;

            if ($result) {
                $cnt = getVisitCount(CM_TIME_YMD);

                $sql = " insert into `{$cm['visit_table']}` ( vi_date, vi_count ) values ( :vi_date, :vi_count ) on duplicate key update vi_count = :vi_count2 ";

                $DB->prepare($sql);
                $DB->execute([':vi_date' => CM_TIME_YMD, ':vi_count' => $cnt, ':vi_count2' => $cnt]);
            }
        }
    }
}

function getVisitCount($date)
{
    $cm = $GLOBALS['cm'];
    $DB = $GLOBALS['DB'];

    $date = date('Y-m-d', strtotime($date));

    $sql = " select count(*) as cnt from `{$cm['visit_log_table']}` where vi_date = :vi_date ";

    $DB->prepare($sql);
    $DB->execute([':vi_date' => $date]);

    $row = $DB->fetch();

    return (int)$row['cnt'];
}

insertVisitLog();

DB는 PDO 방식으로 접근할 수 있도록 했다. 관련 내용은 이 포스트를 참고하면 된다.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.