안녕하세요! 어제는 파일 다운로드를 만들었습니다!
이번에는 조회수 기능을 만들어서 넣겠습니다.
오늘은 간단하게 끝날 것 같아요!
.
.
.
.
우선 게시물 데이터베이스에 조회수를 담을 수 있는 칼럼을 만들겠습니다
이제 board.php로 넘어 가겠습니다.
출력할 때 views도 출력하게 하겠습니다!
sql문 먼저 손 보겠습니다. 가져올 때 id,title,detail이랑 views도 가져오게요
//작성된 게시물들 조회 문
$sql = "SELECT board_id,id,title,views FROM $db_board";
그리고 출력되게 하겠습니다
if(mysqli_num_rows($result) > 0) {
//게시물 출력
while($row = mysqli_fetch_assoc($result)) {
$index = $row['board_id'];
$id = $row['id'];
$title = $row['title'];
echo '<p><a href="view_board.php?index='.$index.'">'.$title.'</a> : '.$id.'작성함 조회수: '.$row['views'].'</p>';
}
} else {
echo "게시물이 없습니다!";
}
이러면 되겠죠
한 번 확인하겠습니다
이제 게시물을 확인할 때 조회수가 1 증가하게 만들겠습니다!
view_board.php에서 코드 손 보면 되겠네요!
//GET방식으로 전달된 index 받는다
$board_id = mysqli_real_escape_string($conn,$_GET['index']);
//조회수 증가하는 sql문
$sql_view = "UPDATE $db_board SET views = views + 1 WHERE board_id = '$board_id'";
//실행
$result_view = mysqli_query($conn, $sql_view);
저기 get방식으로 받을 때 escape로 행여나 sql 공격을 방지하는 코드 추가했습니다
그리고 UPDATE이용해서 1을 더하게 했습니다
그리고 맨 위에다가 조회수가 몇인지 보이게 하겠습니다!
//게시물 출력
while($row = mysqli_fetch_assoc($result)) {
echo '<p>조회수: '.$row['views'].'</p>';
echo '<p>ID: '.$row['id'].'</p>';
echo '<p>Title: '.$row['title'].'</p>';
echo '<p>Detail: '.$row['detail'].'</p>';
echo '<p>Date: '.$row['date'].'</p>';
if (isset($row['file_name'])) {
$file_name = explode('_', $row['file_name'])[1]; // '_' 문자를 기준으로 분리 후 첫번째 요소(파일명)만 가져옵니다.
$download_url = 'download_process.php?filename='.$row['file_name'];
echo '<p>FILE: <a href="'.$download_url.'">'.$file_name.'</a></p>';
}
//로그인한 사용자의 정보 가져온다
$user_id = $_SESSION['login_id'];
//게시물 작성자와 로그인한 ID와 일치한 경우
if($row['id'] == $user_id) {
//게시물 수정 버튼을 보여준다
echo "<form method='POST' action='fix_board.php'>
<input type='hidden' name='board_id' value='".$row['board_id']."'>
<p><button type='submit'>게시물 수정</button></p>
</form>";
//게시물 삭제 버튼을 보여준다
echo "<form method='POST' action='delete_board.php'>
<input type='hidden' name='board_id' value='".$row['board_id']."'>
<p><button type='submit'>삭제</button></p>
</form>";
}
}
이렇게요 한 번 실행해보겠습니다
근데 문제점이 있습니다
새로고침을 하면 계속 조회수가 올라가집니다! 그러니 저는 한 세션이 일정 시간 동안 조회수가 안 올라가지게 하겠습니다!
일단 저는 마지막으로 본 시간을 세션에 저장하게 하겠습니다. 그리고 현재 시간과 차이가 60분 차이 나면 그때 조회수
올라가게 하겠습니다!
// 세션에 마지막 조회 시간 정보가 있는지 확인
if (!isset($_SESSION['last_view_time'])) {
// 세션에 마지막 조회 시간 정보가 없으면 현재 시간을 저장
$_SESSION['last_view_time'] = time();
} else {
// 세션에 마지막 조회 시간 정보가 있으면 일정 시간이 지났는지 확인
$last_view_time = $_SESSION['last_view_time'];
$current_time = time();
$time_diff = $current_time - $last_view_time;
if ($time_diff >= 3600) { // 36600초(1시간) 이상 지났으면 조회수 증가
//조회수 증가하는 sql문
$sql_view = "UPDATE $db_board SET views = views + 1 WHERE board_id = '$board_id'";
//실행
$result_view = mysqli_query($conn, $sql_view);
// 세션에 현재 조회 시간을 저장
$_SESSION['last_view_time'] = $current_time;
}
}
세션 last view_time에 저장되어 있는지 확인해서 없으면 현재 시간을 저장하고
current_time에는 현재 시간을 저장해서
time_diff에 서로 뺀 시간을 저장하게 됩니다! 이는 초단위로 계산이 됩니다
그래서 1시간이면 3600초 적으면 되겠죠
근데 지금 개발 중인데 1시간을 기다릴 시간 없습니다 잠깐 10초으로 설정하고 하겠습니다
if ($time_diff >= 10) { // 36600초(1시간) 이상 지났으면 조회수 증가
잠깐 이러고 실행해보겠습니다!
근데 문제점이 있네요 세션이 다 같이 할당해서 다른 게시물이 안 올라가집니다!
그러니 코드를 조금 수정하겠습니다
//가독성 위해 다른 변수에 저장
$last_viewed_time_for_board_id = 'last_view_time_'.$board_id;
// 세션에 마지막 조회 시간 정보가 있는지 확인
if (!isset($_SESSION[$last_viewed_time_for_board_id])) {
// 세션에 마지막 조회 시간 정보가 없으면 현재 시간을 저장
$_SESSION[$last_viewed_time_for_board_id] = time();
} else {
// 세션에 마지막 조회 시간 정보가 있으면 일정 시간이 지났는지 확인
$last_view_time = $_SESSION[$last_viewed_time_for_board_id];
$current_time = time();
$time_diff = $current_time - $last_view_time;
if ($time_diff >= 10) { // 36600초(1시간) 이상 지났으면 조회수 증가
//조회수 증가하는 sql문
$sql_view = "UPDATE $db_board SET views = views + 1 WHERE board_id = '$board_id'";
//실행
$result_view = mysqli_query($conn, $sql_view);
// 세션에 현재 조회 시간을 저장
$_SESSION[$last_viewed_time_for_board_id] = $current_time;
}
}
변수명이 좀 길지만 가독성을 위해서 이렇게 했습니다.
다시 해보겠습니다
조금만 더 기다리고 새로고침 하면??
이제 10초 간격을 늘려서 1시간으로 바꾸겠습니다
오늘은 이렇게 조회수 기능을 만들어 봤습니다!
다음에는 좋아요도 넣어보겠습니다!
감사합니다
.
.
.
.
.
-view_board.php
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>게시물 보는중</title>
</head>
<body>
<p>
<?php
include 'DB_INFO.php'; //데이터 베이스 정보
//데이터베이스 연결
$conn = mysqli_connect($host,$username,$password,$db_board);
//데이터베이스 오류시 종료
if(mysqli_connect_errno()) {
die("데이터 베이스 오류: ". mysqli_connect_error());
}
session_start(); //세션 시작
if(!isset($_SESSION['login_id'])) {
//로그인하지 않은 사용자
header("Location: login.php"); //login 화면으로 바꾼다
exit(); //이 페이지를 바로 닫는다
}
//GET방식으로 전달된 index 받는다
$board_id = mysqli_real_escape_string($conn,$_GET['index']);
//가독성 위해 다른 변수에 저장
$last_viewed_time_for_board_id = 'last_view_time_'.$board_id;
// 세션에 마지막 조회 시간 정보가 있는지 확인
if (!isset($_SESSION[$last_viewed_time_for_board_id])) {
// 세션에 마지막 조회 시간 정보가 없으면 현재 시간을 저장
$_SESSION[$last_viewed_time_for_board_id] = time();
} else {
// 세션에 마지막 조회 시간 정보가 있으면 일정 시간이 지났는지 확인
$last_view_time = $_SESSION[$last_viewed_time_for_board_id];
$current_time = time();
$time_diff = $current_time - $last_view_time;
if ($time_diff >= 3600) { // 36600초(1시간) 이상 지났으면 조회수 증가
//조회수 증가하는 sql문
$sql_view = "UPDATE $db_board SET views = views + 1 WHERE board_id = '$board_id'";
//실행
$result_view = mysqli_query($conn, $sql_view);
// 세션에 현재 조회 시간을 저장
$_SESSION[$last_viewed_time_for_board_id] = $current_time;
}
}
//작성된 게시물들 조회 문
$sql = "SELECT * FROM $db_board WHERE board_id = '$board_id' ";
//쿼리문 실행
$result = mysqli_query($conn, $sql);
//게시물 출력
while($row = mysqli_fetch_assoc($result)) {
echo '<p>조회수: '.$row['views'].'</p>';
echo '<p>ID: '.$row['id'].'</p>';
echo '<p>Title: '.$row['title'].'</p>';
echo '<p>Detail: '.$row['detail'].'</p>';
echo '<p>Date: '.$row['date'].'</p>';
if (isset($row['file_name'])) {
$file_name = explode('_', $row['file_name'])[1]; // '_' 문자를 기준으로 분리 후 첫번째 요소(파일명)만 가져옵니다.
$download_url = 'download_process.php?filename='.$row['file_name'];
echo '<p>FILE: <a href="'.$download_url.'">'.$file_name.'</a></p>';
}
//로그인한 사용자의 정보 가져온다
$user_id = $_SESSION['login_id'];
//게시물 작성자와 로그인한 ID와 일치한 경우
if($row['id'] == $user_id) {
//게시물 수정 버튼을 보여준다
echo "<form method='POST' action='fix_board.php'>
<input type='hidden' name='board_id' value='".$row['board_id']."'>
<p><button type='submit'>게시물 수정</button></p>
</form>";
//게시물 삭제 버튼을 보여준다
echo "<form method='POST' action='delete_board.php'>
<input type='hidden' name='board_id' value='".$row['board_id']."'>
<p><button type='submit'>삭제</button></p>
</form>";
}
}
?>
</p>
<p>
<?php session_start();
if (isset($_SESSION['write_error'])) {
echo $_SESSION['write_error'];
unset($_SESSION['write_error']);
}
?>
</p>
<p>
<?php session_start();
if (isset($_SESSION['file_error'])) {
echo $_SESSION['file_error'];
unset($_SESSION['file_error']);
}
?>
</p>
<p></p>
<form action="write_board.php" method="POST">
<p><input type="submit" name="write" value="게시판 작성"></p>
</form>
<form action="board.php">
<p><input type="submit" value="메인페이지로"></p>
</form>
</body>
</html>
-board.php
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Welcome!</title>
</head>
<body>
<h1>MENU</h1>
<form method ="POST" action="board.php">
<input type = "text" name="search" placeholder="검색">
<input type="submit" value="검색">
</form>
<p>
<?php
include 'DB_INFO.php'; //데이터 베이스 정보
//데이터베이스 연결
$conn = mysqli_connect($host,$username,$password,$db_board);
//데이터베이스 오류시 종료
if(mysqli_connect_errno()) {
die("데이터 베이스 오류: ". mysqli_connect_error());
}
session_start(); //세션 시작
if(!isset($_SESSION['login_id'])) {
//로그인하지 않은 사용자
header("Location: login.php"); //login 화면으로 바꾼다
exit(); //이 페이지를 바로 닫는다
}
//한 페이지에 보여줄 게시물 수
$num_per_page = 5;
//현재 페이지 번호
if(isset($_GET['page'])) {
$page = intval($_GET['page']);
} else {
$page = 1;
}
//전체 게시물 수 조회
$total_sql = "SELECT count(*) AS cnt FROM $db_board";
$total_result = mysqli_query($conn,$total_sql); //sql문 실행
$total_row = mysqli_fetch_assoc($total_result); //결과를 배열로 가져온다
$total_posts = $total_row['cnt']; //배열 중 cnt의 값을 가져온다
//전체 페이지 수
$total_pages = ceil($total_posts / $num_per_page);
//각 페이지 시작 인덱스
$start = ($page - 1) * $num_per_page;
//작성된 게시물들 조회 문
$sql = "SELECT board_id,id,title,views FROM $db_board";
//검색이 입력된 경우
if(isset($_POST['search']) && !empty($_POST['search'])) {
$search = mysqli_real_escape_string($conn, $_POST['search']);
$sql = "SELECT board_id,id,title FROM $db_board WHERE title LIKE '%$search%'";
$total_sql = "SELECT count(*) AS cnt FROM $db_board WHERE title LIKE '%$search%'";
}
//sql문에 추가로 작성하고 LIMIT 설정하고 DESC 즉 내림차순으로 정렬
$sql .= " ORDER BY board_id DESC LIMIT $start, $num_per_page";
//쿼리문 실행
$result = mysqli_query($conn, $sql);
if(mysqli_num_rows($result) > 0) {
//게시물 출력
while($row = mysqli_fetch_assoc($result)) {
$index = $row['board_id'];
$id = $row['id'];
$title = $row['title'];
echo '<p><a href="view_board.php?index='.$index.'">'.$title.'</a> : '.$id.'작성함 조회수: '.$row['views'].'</p>';
}
} else {
echo "게시물이 없습니다!";
}
echo '<p> [ ';
// 현재 페이지를 10으로 나눈 몫에 10을 곱한 값에서 1을 빼면
// 현재 페이지가 몇 번째 페이지 블록에 있는지 알 수 있습니다.
$block_start = floor(($page-1)/10)*10;
if ($block_start > 1) {
// 이전 페이지 블록이 있다면, 다음 버튼을 출력합니다.
$next_block_start = $block_start - 10;
if($next_block_start == 0) {
$next_block_start += 1; //0페이지는 존재 하지 않기에 1더한다
}
echo '<a href="?page=' . $next_block_start .'"><< </a>';
}
// 이전 버튼 출력
if ($page > 1) {
echo '<a href="?page=' . ($page-1) .'">< </a> ';
}
// 페이지 링크 출력
for ($i = $block_start+1; $i <= min($block_start+10, $total_pages); $i++) {
if($i == $page) {
echo '<strong>'.$i.' </strong>';
} else {
echo '<a href="?page=' . $i .'">'.$i. '</a> ';
}
echo ' ';
}
// 다음 버튼 출력
if ($page < $total_pages) {
echo '<a href="?page=' . ($page+1) .'">> </a> ';
}
if ($block_start+10 < $total_pages) {
// 다음 페이지 블록이 있다면, 다음 버튼을 출력합니다.
$next_block_start = $block_start + 11;
echo '<a href="?page=' . $next_block_start .'">>></a>';
}
echo ' ]</p>';
?>
</p>
<p></p>
<form action="write_board.php" method="POST">
<p><input type="submit" name="write" value="게시판 작성"></p>
</form>
<form action="only_login.php">
<p><input type="submit" value="메인페이지로"></p>
</form>
</body>
</html>
-4/20 보안 관련해서 코드 조금 더 수정 했습니다!
https://mynameisarke.tistory.com/24
[노말틱 모의 해킹 취업반 개발과제 (2)] 보안 관련해서 보완 하기
안녕하세요! 이태까지 제가 만든 웹 사이트에 보안을 좀 더 보완하겠습니다! 오늘은 파일 업로드에 보안을 좀 더 강화하겠습니다 저는 지정한 디렉터리에 저장을 하게 했는데 이는 적절한 보안
mynameisarke.tistory.com
'개발과제' 카테고리의 다른 글
[노말틱 모의 해킹 취업반 9주차 개발과제 ] 게시판 만들기(5) - 좋아요기능 (0) | 2023.04.24 |
---|---|
[노말틱 모의 해킹 취업반 9주차 개발과제 ] 게시판 만들기(5) - 날짜 검색 (1) | 2023.04.22 |
[노말틱 모의 해킹 취업반 8주차 개발과제 ] 게시판 만들기(4) - 파일 업로드 (0) | 2023.04.18 |
[노말틱 모의 해킹 취업반 7주차 개발과제 ] 게시판 만들기(3) - 페이징 (0) | 2023.04.17 |
[노말틱 모의 해킹 취업반 6주차 개발과제 ] 게시판 만들기(2) - 수정, 삭제, 검색 (0) | 2023.04.16 |