[php] 간단한 웹페이지 방문자 카운터 만들기
급하게, 단순하게 방문자 카운터가 필요해서 만들어 봤다. (그냥 단순하게 카운팅 및 표시만 되면 됨.)
일단 잠간 검색을 하고, 아래 포스팅을 참고해서 작성했다.
https://blog.naver.com/blackboys20/221556240376
글쓴 분은 레이어 생성해서 이쁘게 하셨지만..
난 그냥 단순하게 숫자만 나오면 되기에.. 최대한 단순하게..
DB고 뭐고, 성능이고 뭐고.. 상관없이 그냥 파일에 단순하게 기록하는걸로..
혹시 나처럼 간단한 카운터가 필요한 사람을 위해 남겨놓는다.
우선 완성된 소스는 다음과 같다.
방문자 카운터 소스 (counter.php)
[user@localhost public_html]$ cat counter.php <?php $cnt_total = 0; $cnt_today = 0; function getCount() { global $cnt_total, $cnt_today; $fname_str = "./count.txt"; $list = file( $fname_str); $cnt_total = chop($list[0]); $cnt_today = chop($list[1]); $standard_time = chop($list[2]); $cur_time = date("Y-m-d H:i:s"); $time_cal = strtotime($standard_time)-strtotime($cur_time); $ip = $_COOKIE['ip']; // 쿠키를 사용한 일정시간 중복카운팅 배제 $ip = ""; // 중복허용하려면 ip 삭제(테스트라 중복 허용) if( $time_cal<0 ) { $cnt_today = 0; $standard_time = date( "Y-m-d H:i:s", strtotime( date("Y-m-d")."+1 day") ); } if( !$ip ) { $cnt_total++; $cnt_today++; setcookie( "ip", $_SERVER["REMOTE_ADDR"], time()+300 ); } $file_open = fopen( $fname_str, "w" ); fwrite( $file_open, $cnt_total."\n".$cnt_today."\n".$standard_time); fclose($file_open); } getCount(); if($_GET['mode'] == 'counter') { $json = []; $json['total'] = $cnt_total; $json['today'] = $cnt_today; echo json_encode($json); } ?> [user@localhost public_html]$
원본글에서는 html파일이나 php에 jQuery와 ajax통신으로 표시하도록 되어있었는데, 나는 조금 수정했다.
생각해보니, 카운팅 되는 페이지가 php파일이면 그냥 include해서 써도 되지 안을까? 싶어서..
결국 둘다 사용 가능하도록 바꿨다.
잠간 소스 설명을 하자면…
<?php $cnt_total = 0; $cnt_today = 0; function getCount() { global $cnt_total, $cnt_today;
우선, 다른 php에 include 될 수 있게 되면서, 변수 스코프를 생각해서 카운팅 변수는 전역변수로 사용하고, 나머지 로컬변수는 함수(getCount())로 감쌌다.
$fname_str = "./count.txt"; $list = file( $fname_str); $cnt_total = chop($list[0]); $cnt_today = chop($list[1]); $standard_time = chop($list[2]);
데이터 파일명을 선언하고, 해당 파일을 읽어온다.
데이터는 3줄이며, 첫줄엔 총 방문자, 둘째줄엔 오늘 방문자, 세째줄엔 오늘 방문자를 초기화하기 위한 날짜(내일 00시)가 들어가있다.
$cur_time = date("Y-m-d H:i:s"); $time_cal = strtotime($standard_time)-strtotime($cur_time); $ip = $_COOKIE['ip']; // 쿠키를 사용한 일정시간 중복카운팅 배제 $ip = ""; // 중복허용하려면 ip 삭제(테스트라 중복 허용) if( $time_cal<0 ) { $cnt_today = 0; $standard_time = date( "Y-m-d H:i:s", strtotime( date("Y-m-d")."+1 day") ); }
오늘 방문자 계산을 위해 현재시간($cur_time)을 구하고, 저장된 시간($standard_time)과 비교하여 오늘이 지났는지(?) 계산한다.
저장된 시간이 지났으면($time_cal<0), 오늘 카운트를 초기화하고, 오늘( date(“Y-m-d”)에서 시간을 안정했으므로 00시가 된다.)에서 하루를 더해서 $standard_time을 새로 만든다.
중복배제를 위해 세팅해놓은 쿠키값($_COOKIE[‘ip’])을 읽어온다.
if( !$ip ) { $cnt_total++; $cnt_today++; setcookie( "ip", $_SERVER["REMOTE_ADDR"], time()+300 ); }
쿠키로 불러온 $ip값이 없으면(중복 체크) 총 카운트 증가, 오늘카운트 증가, 중복제거를 위한 쿠기를 세팅한다.
쿠키세팅할때 3번째 변수(time()+300)를 통해 쿠키 생존기간을 정할수 있고, 중복체크 시간을 조정할 수 있다. 단위는 초 단위이며, 위 코드에서는 300초(5분)동안 카운팅을 무시한다.
$file_open = fopen( $fname_str, "w" ); fwrite( $file_open, $cnt_total."\n".$cnt_today."\n".$standard_time); fclose($file_open); } getCount();
파일이 변경된 값(총 방문자, 오늘 방문자, 기준시간)을 저장한다.
선언된 함수를 실행하여 카운팅을 적용한다.
if($_GET['mode'] == 'counter') { $json = []; $json['total'] = $cnt_total; $json['today'] = $cnt_today; echo json_encode($json); }
ajax으로 호출 할 경우를 대비하여 mode=counter 라는 인자가 넘어오면 값을 JSON방식으로 출력하여 전달해준다.
여기까지가 카운터 소스 설명이고.. 실제 호출하는 방법을 알아보자.
우선 html이나 스킨 같은데서.. ajax를 통해 호출하는 소스이다.
활용방법 1 (ajax 등을 활용 – html, 테마 등에 적용)
[user@localhost public_html]$ cat viewer.html <!DOCTYPE html> <html lang="ko"> <head> <title>counter page</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> </head> <body> <center> 안녕하세요?<br> 오늘 방문객은 <span id='today_val'>0</span>명, 총 방문객은 <span id='total_val'>0</span>명 입니다. </center> <script> $.get('./counter.php?mode=counter', function(data) { cntData = JSON.parse(data); $('#total_val').text(cntData.total); $('#today_val').text(cntData.today); }); </script> </body> </html> [user@localhost public_html]$
간단히 소스 설명을 하자면..
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<head>태그 안에.. ajax, jQuery를 위한 스크립트를 넣고,
오늘 방문객은 <span id='today_val'>0</span>명, 총 방문객은 <span id='total_val'>0</span>명 입니다.
본문 내용에 오늘 방문객과 총 방문객이 출력될 객체를 정해준다. 객체의 ID는 각각 ‘today_val’과 ‘total_val’ 이다. (물론 밑이랑 맞춰주면 바꿔도 된다.)
<script> $.get('./counter.php?mode=counter', function(data) { cntData = JSON.parse(data); $('#total_val').text(cntData.total); $('#today_val').text(cntData.today); }); </script>
ajax으로.. counter.php 를 mode=counter 인자를 넣어 실행한다. 실행값은 cntData라는 JSON객체로 받는다. (각각 cntData.total, cntData.today 로 넘어온다.)
본문에 정해줬던 ID를 찾아 값을 넣어준다.
근데, 이방법을 썼더니.. 좀 깜박이는 증상이 발생..(내가 적용시킨 파일이 용량이 좀 컸었나보다. 화면을 불러온 뒤, 방문객 숫자가 깜박 하면서 바뀐다.)
그래서 아래와 같은 방법도 가능토록 했다.
활용방법 2 (php파일에 include)
[user@localhost public_html]$ cat viewer.php <?php include 'counter.php' ?> <!DOCTYPE html> <html lang="ko"> <head> <title>counter page</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no"> </head> <body> <center> 안녕하세요?<br> 오늘 방문객은 <span id='today_val'><?=$cnt_today?></span>명, 총 방문객은 <span id='total_val'><?=$cnt_total?></span>명 입니다. </center> </body> </html> [user@localhost public_html]$
별다른 내용은 없어서 따로 설명은 안적는다. 그냥 counter.php 를 include 하고, include하면서 전역변수 $cnt_today, $cnt_total 에 값이 저장되어있으니, 해당 값을 출력한다.
<head>에서.. jquery 불러올 필요도 없고, 본문에 값을 적용시켜주고자 script를 한번 더 호출할 필요도 없고.. 소스 자체는 간단해졌다. php 가 가능하면 그냥 이방법이 더 나은듯.