12. PHP 게시판 만들기, list 제작 2

2015.04.16 00:22
저자 : Kurien

주의: 본 게시판은 보안을 생각하지 않고 만들어졌으므로 실제로 사용되어서는 안되는 코드입니다.

공부할 때 게시판이 이처럼 동작한다는 정도로만 이해해주세요.


오늘은 페이징에 대해서 알아보겠습니다.

오늘은 조금 복잡하니 잘 따라오세요!

먼저 오늘 수정된 파일을 받아봅시다.


20150415_project.zip


코드를 설명하기에 앞서 페이징에 대해서 설명드리겠습니다.

페이징이라는건 주로 게시판 목록에서 하단에 존재하는 1 ~ 10, 11 ~ 20과 같이 각 페이지를 볼 수 있게하는 기능을 말합니다.

이런 기능이 필요한 이유가 뭘까요?



먼저 한 목록에 모든 페이지가 나오게 되면 스크롤이 길어집니다.

사용자가 가독성이 떨어지게 되고 글을 찾기도 힘들죠.


그리고 요청 데이터가 많은 만큼 페이지의 로딩 속도(모바일의 경우 데이터 문제도 있음)도 많이 느려지겠죠.


하지만 가장 중요한 부분은 페이징 기능을 사용함으로써 DB에 대한 부하가 줄어듭니다.

만약 게시판에 10000개의 글이 존재하는 게시판에 만명의 사용자가 들어왔는데, 모든 글을 출력해준다고 하면 어떻게 될까요?

모두에게 10000개의 글을 보여주기 전에 DB 서버가 과부하가 걸려서 멈출겁니다.


페이징을 사용하게 되면 적당한 양의 글을 나눠서 보여줄 수 있습니다.

이제 코드를 보며 페이징의 작동 방식을 알아봅시다.


아래의 코드는 index.php 부분입니다.


<?php

require_once("../dbconfig.php");

/* 페이징 시작 */

//페이지 get 변수가 있다면 받아오고, 없다면 1페이지를 보여준다.

if(isset($_GET['page'])) {

$page = $_GET['page'];

} else {

$page = 1;

}

$sql = 'select count(*) as cnt from board_free order by b_no desc';

$result = $db->query($sql);

$row = $result->fetch_assoc();

$allPost = $row['cnt']; //전체 게시글의 수

$onePage = 15; // 한 페이지에 보여줄 게시글의 수.

$allPage = ceil($allPost / $onePage); //전체 페이지의 수

if($page < 1 || ($allPage && $page > $allPage)) {

?>

<script>

alert("존재하지 않는 페이지입니다.");

history.back();

</script>

<?php

exit;

}

$oneSection = 10; //한번에 보여줄 총 페이지 개수(1 ~ 10, 11 ~ 20 ...)

$currentSection = ceil($page / $oneSection); //현재 섹션

$allSection = ceil($allPage / $oneSection); //전체 섹션의 수

$firstPage = ($currentSection * $oneSection) - ($oneSection - 1); //현재 섹션의 처음 페이지

if($currentSection == $allSection) {

$lastPage = $allPage; //현재 섹션이 마지막 섹션이라면 $allPage가 마지막 페이지가 된다.

} else {

$lastPage = $currentSection * $oneSection; //현재 섹션의 마지막 페이지

}

$prevPage = (($currentSection - 1) * $oneSection); //이전 페이지, 11~20일 때 이전을 누르면 10 페이지로 이동.

$nextPage = (($currentSection + 1) * $oneSection) - ($oneSection - 1); //다음 페이지, 11~20일 때 다음을 누르면 21 페이지로 이동.

$paging = '<ul>'; // 페이징을 저장할 변수

//첫 페이지가 아니라면 처음 버튼을 생성

if($page != 1) { 

$paging .= '<li class="page page_start"><a href="./index.php?page=1">처음</a></li>';

}

//첫 섹션이 아니라면 이전 버튼을 생성

if($currentSection != 1) { 

$paging .= '<li class="page page_prev"><a href="./index.php?page=' . $prevPage . '">이전</a></li>';

}

for($i = $firstPage; $i <= $lastPage; $i++) {

if($i == $page) {

$paging .= '<li class="page current">' . $i . '</li>';

} else {

$paging .= '<li class="page"><a href="./index.php?page=' . $i . '">' . $i . '</a></li>';

}

}

//마지막 섹션이 아니라면 다음 버튼을 생성

if($currentSection != $allSection) { 

$paging .= '<li class="page page_next"><a href="./index.php?page=' . $nextPage . '">다음</a></li>';

}

//마지막 페이지가 아니라면 끝 버튼을 생성

if($page != $allPage) { 

$paging .= '<li class="page page_end"><a href="./index.php?page=' . $allPage . '">끝</a></li>';

}

$paging .= '</ul>';

/* 페이징 끝 */

$currentLimit = ($onePage * $page) - $onePage; //몇 번째의 글부터 가져오는지

$sqlLimit = ' limit ' . $currentLimit . ', ' . $onePage; //limit sql 구문

$sql = 'select * from board_free order by b_no desc' . $sqlLimit; //원하는 개수만큼 가져온다. (0번째부터 20번째까지

$result = $db->query($sql);

?>

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8" />

<title>자유게시판 | Kurien's Library</title>

<link rel="stylesheet" href="./css/normalize.css" />

<link rel="stylesheet" href="./css/board.css" />

</head>

<body>

<article class="boardArticle">

<h3>자유게시판</h3>

<div id="boardList">

<table>

<caption class="readHide">자유게시판</caption>

<thead>

<tr>

<th scope="col" class="no">번호</th>

<th scope="col" class="title">제목</th>

<th scope="col" class="author">작성자</th>

<th scope="col" class="date">작성일</th>

<th scope="col" class="hit">조회</th>

</tr>

</thead>

<tbody>

<?php

while($row = $result->fetch_assoc())

{

$datetime = explode(' ', $row['b_date']);

$date = $datetime[0];

$time = $datetime[1];

if($date == Date('Y-m-d'))

$row['b_date'] = $time;

else

$row['b_date'] = $date;

?>

<tr>

<td class="no"><?php echo $row['b_no']?></td>

<td class="title">

<a href="./view.php?bno=<?php echo $row['b_no']?>"><?php echo $row['b_title']?></a>

</td>

<td class="author"><?php echo $row['b_id']?></td>

<td class="date"><?php echo $row['b_date']?></td>

<td class="hit"><?php echo $row['b_hit']?></td>

</tr>

<?php

}

?>

</tbody>

</table>

<div class="btnSet">

<a href="./write.php" class="btnWrite btn">글쓰기</a>

</div>

<div class="paging">

<?php echo $paging ?>

</div>

</div>

</article>

</body>

</html>


지금까지와는 다르게 프로그램 부분이 매우 길게 느껴지네요.

주석을 달아놓긴 했지만, 차근차근 나눠서 자세한 설명을 진행하겠습니다.


/* 페이징 시작 */

//페이지 get 변수가 있다면 받아오고, 없다면 1페이지를 보여준다.

if(isset($_GET['page'])) {

$page = $_GET['page'];

} else {

$page = 1;

}


먼저 페이징 시작 부분입니다.

page라는 get 변수를 이용해서 페이징을 구현할텐데, 먼저 $_GET['page']가 있다면 $page에 넣어줍니다.

만약 $_GET['page']의 값이 없다면 $page에는 1을 넣어줍니다.


1을 넣어주는 이유는 만약 http://kurien.co.kr/project/board/ 이 주소로 접속을 했을 때는 get 변수가 존재하지 않게 되는데,

$_GET['page']가 없을 때 $page가 1이라면 위의 주소와 같은 경우에도 첫 페이지를 정상적으로 볼 수 있게 됩니다.


$sql = 'select count(*) as cnt from board_free';

$result = $db->query($sql);

$row = $result->fetch_assoc();


$allPost = $row['cnt']; //전체 게시글의 수


$onePage = 15; // 한 페이지에 보여줄 게시글의 수.

$allPage = ceil($allPost / $onePage); //전체 페이지의 수


if($page < 1 || ($allPage && $page > $allPage)) {

?>

<script>

alert("존재하지 않는 페이지입니다.");

history.back();

</script>

<?php

exit;

}


여기서 $sql 부분은 select 문을 이용해서 board_free 테이블 내의 모든 행의 개수를 가져옵니다.

여기서 행 = 게시 글이므로 모든 게시 글의 수를 말합니다.


그리고 그 값($row['cnt'])를 $allPost에 넣습니다.

$allPost에는 전체 게시글 수가 들어있겠죠?


이번엔 $onePage를 선언하는데요.

$onePage 변수에는 한 페이지에 보여질 게시물의 수를 넣어줍니다.

주로 이용되는 게시판은 10~20개의 글이 보여지는게 일반적인 것으로 알고 있습니다.

저는 15개를 보여지게 할 생각이므로 15를 넣었습니다.


다음은 $allPage입니다.

$allPost는 전체 게시글 수 였다면 $allPage는 전체 페이지의 수입니다.

연산을 보면 $allPost(전체 게시글 수) / $onePage(한 페이지에 보일 게시글 수)인데, 이 값을 ceil 함수가 감싸고 있습니다.

ceil 함수는 올림, 반올림, 내림에서 올림을 나타냅니다.


여기서 전체 게시글이 400개라고 가정했을 때 전체 페이지는 400 / 15 = 26.666을 올림 한 27이 됩니다.

올림을 하는 이유는 400개의 글까지는 26 페이지까지 다 보이겠지만 27페이지가 없다면 나머지 10개의 글을 볼 수 없기 때문이죠.


$allPage까지 구했다면 $page가 1보다 작거나 $allPage보다 큰지 확인을 해봅니다.

$page가 1보다 작거나 $allPage보다 클 수는 없으므로 이 경우는 사용자가 잘못된 경로를 이용한다는 뜻입니다.

잘못된 경로이니 경고를 출력하고 이전 화면으로 돌려보내줍니다.


$oneSection = 10; //한번에 보여줄 총 페이지 개수(1 ~ 10, 11 ~ 20 ...)

$currentSection = ceil($page / $oneSection); //현재 섹션

$allSection = ceil($allPage / $oneSection); //전체 섹션의 수


$firstPage = ($currentSection * $oneSection) - ($oneSection - 1); //현재 섹션의 처음 페이지


if($currentSection == $allSection) {

$lastPage = $allPage; //현재 섹션이 마지막 섹션이라면 $allPage가 마지막 페이지가 된다.

} else {

$lastPage = $currentSection * $oneSection; //현재 섹션의 마지막 페이지

}


$prevPage = (($currentSection - 1) * $oneSection); //이전 페이지, 11~20일 때 이전을 누르면 10 페이지로 이동.

$nextPage = (($currentSection + 1) * $oneSection) - ($oneSection - 1); //다음 페이지, 11~20일 때 다음을 누르면 21 페이지로 이동.


여기서는 Section 변수를 선언하네요.

Section과 관련된 변수는 다른 분들은 Block으로 쓰는데, 저는 그냥 Section이 맘에 드니 Section으로 하겠습니다.


먼저 Section이란건 1 ~ 10, 11 ~ 20, 21 ~ 30 ... 과 같은 페이지 번호가 있을 때 1 ~ 10을 1 섹션으로 정했습니다.

11 ~ 20의 경우에는 2 섹션, 21 ~ 30은 3 섹션이죠.


이렇게 10개의 페이지 번호가 1 섹션임을 나타내는 변수가 $oneSection입니다.

값이 10으로 되어있죠?


그리고 $currentSection은 현재 Section을 나타내는 변수입니다.

$page(현재 페이지)를 $oneSection(10)으로 나눈 값을 올림한 값입니다.

현재 페이지가 22페이지라면 현재 Section은 3이 되겠죠.

이 변수는 뒤에 나올 변수를 연산하는데 쓰입니다.


$allSection은 $allPage(전체 페이지 수 27)를 $oneSection(10)으로 나눴으므로 2.7이 되고, 이 부분도 마찬가지로 올림을 합니다.

여기선 3이란 값을 갖겠네요.


$firstPage는 현재 섹션의 처음 페이지, $currentSection이 3이라면 21 ~ 30의 페이지를 출력해야 하는데,

여기서 21이란 값을 구하기 위한 부분입니다.

$currentSection(현재 섹션 값 3) * $oneSection(10)을 계산하고, 거기에서 $oneSection - 1(9)를 빼줍니다.

그러므로 30 - 9 = 21, 즉 3 섹션의 첫 번째 페이지인 21이란 값이 나오게 되는거죠.


$lastPage는 반대로 현재 섹션의 마지막 페이지를 나타냅니다.

그런데 이 부분은 if와 else로 나눠져 있죠?

여기서는 조금 더 생각을 해야하는게, 3 섹션이라고 하더라도 마지막 페이지는 반드시 30이 아닙니다.

글이 400개일 때 총 페이지는 27이므로 마지막 페이지는 페이지 27겠죠?


이 부분 때문에 $allSection을 구한건데요,

만약 $currentSection(현재 섹션)과 $allSection(마지막 섹션)이 같다면, $lastPage는 $allPage로 대체합니다.

$currentSection과 $allSection이 다르다면 마지막 페이지를 구해주는데, $currentSection * $onePage가 마지막 페이지가 됩니다.


페이지 변수 선언 부분의 마지막으로 $prevPage와 $nextPage 부분이 있습니다.

$prevPage는 이전, $nextPage는 다음을 나타내는데 이전을 눌렀을 때는 이전 섹션의 마지막 페이지(21 ~ 30 기준 20)로 이동하고,

다음을 눌렀을 때는 다음 섹션의 첫 번째 페이지(21 ~ 30 기준 31)로 이동합니다.


연산은 이전은 현재 섹션에 -1을 했고, 다음은 +1을 했습니다.

다음일 경우에는 +1 만으로는 안되기 때문에 ($onePage-1) 값(9)을 더 빼줬습니다.


$paging = '<ul>'; // 페이징을 저장할 변수


//첫 페이지가 아니라면 처음 버튼을 생성

if($page != 1) { 

$paging .= '<li class="page page_start"><a href="./index.php?page=1">처음</a></li>';

}

//첫 섹션이 아니라면 이전 버튼을 생성

if($currentSection != 1) { 

$paging .= '<li class="page page_prev"><a href="./index.php?page=' . $prevPage . '">이전</a></li>';

}


for($i = $firstPage; $i <= $lastPage; $i++) {

if($i == $page) {

$paging .= '<li class="page current">' . $i . '</li>';

} else {

$paging .= '<li class="page"><a href="./index.php?page=' . $i . '">' . $i . '</a></li>';

}

}


//마지막 섹션이 아니라면 다음 버튼을 생성

if($currentSection != $allSection) { 

$paging .= '<li class="page page_next"><a href="./index.php?page=' . $nextPage . '">다음</a></li>';

}


//마지막 페이지가 아니라면 끝 버튼을 생성

if($page != $allPage) { 

$paging .= '<li class="page page_end"><a href="./index.php?page=' . $allPage . '">끝</a></li>';

}

$paging .= '</ul>';

/* 페이징 끝 */


여기부터는 실제로 태그로 출력할 내용을 변수에 저장하는 부분입니다.

저는 ul과 li 태그를 이용해서 리스트를 작성했기 때문에 먼저 $paging에 <ul>이라는 값을 넣어주면서 초기화 시킵니다.


그 다음 처음 버튼을 만드는데 처음 버튼이 존재 해야 할 상황은 $page(현재 페이지)의 값이 1이 아닐 때입니다.

그러므로 $page != 1일 때 처음 버튼을 만들어 주는거죠.


이전 버튼은 $currentSection이 1이 아닐 때 만들어줍니다.

1~10일 때 이전 버튼이 있어버리면 있지도 않은 0페이지로 이동해버리겠죠?

이전 버튼의 $paging .= 부분을 보시면 위에서 만든 $prevPage 변수가 사용되는 것을 보실 수 있습니다.


다음 버튼과 끝 버튼 전에 for문이 하나 나오는데요,

여기는 1 ~ 10, 11 ~ 20, 21 ~ 30 ...과 같은 페이지들을 만들어 주는 부분입니다.

먼저 $i는 위에서 만든 $firstPage 변수로 초기화 하고, $lastPage와 같아질 때까지 반복해줍니다.

여기서도 if문이 있는데, 만약 $i의 값이 $page(현재 페이지)와 같을 경우엔 current라는 클래스를 넣어주고, 앵커 태그(<a>)가 없애줬습니다.

$i가 같지 않다면 current는 없고 앵커 태그(<a>)가 있겠죠?


for를 이용해 페이지를 만들었다면 다음 버튼을 만들 차례입니다.

다음 버튼은 이전 버튼과 비슷한데, 주의할 부분은 조건 부분의 1이 $allSection으로 바뀌고 $prevPage가 $nextPage로 변경 된 정도겠네요.


끝 버튼도 처음 버튼과 비슷합니다.

조건 부분의 1이 $allPage로 바뀌고 $paging .=의 1이 $allPage로 바뀌었습니다.


페이징 부분을 모두 작성 했으니 </ul>태그로 닫아줍니다.

여기까지 페이징 기능은 끝입니다.


이제 페이징에 맞게 sql을 변경하고 출력하는 부분입니다.


$currentLimit = ($onePage * $page) - $onePage; //몇 번째의 글부터 가져오는지

$sqlLimit = ' limit ' . $currentLimit . ', ' . $onePage; //limit sql 구문


$sql = 'select * from board_free order by b_no desc' . $sqlLimit; //원하는 개수만큼 가져온다. (0번째부터 20번째까지

$result = $db->query($sql);


이 부분은 list 제작 1에서 만들었던 부분을 가지고 수정했습니다.

비교해보시면 아시겠지만 코드 뿐만 아니라 위치도 파란색으로 표시된 부분에서 상단으로 조금 옮겼습니다.


여기서 $currentLimit는 현재 페이지에 따라 가져올 부분을 정해줍니다.

$sqlLimit 변수에 들어가는 변수인데, sql 전체를 함께 설명드리겠습니다.


select * from board_free order by b_no desc limit 0, 15;와 같은 sql이 있다고 할 때 이 부분을 해석하자면,

board_free 테이블에서 b_no을 기준으로 내림차순 정렬된 데이터 중 0번부터 15개의 행을 출력하라.

라는 의미입니다.


"0번째 부터 15개의 행을 출력하라." 라는 부분이 $sqlLimit이고, 여기서 "0번째"가 $currentLimit 부분입니다.

$currentLimit는 1 페이지일 때 ($onePage(15) * $page(1)) - $onePage(15) 이므로 15 - 15 = 0,

1 페이지일 때 0번째 글부터 출력하게 되고, 2페이지일 때는 (15 * 2) - 15가 되므로 15번째 글부터 출력하는거죠.


이런식으로 몇 번째부터 글을 출력하느냐가 페이징의 핵심입니다.


<div class="paging">

<?php echo $paging ?>

</div>


마지막으로 $paging에 저장 했던 페이징 태그들을 이와같이 출력해줍니다.



이렇게 페이징 기능을 구현해서 모든 글을 여러 페이지로 나누어 보여줄 수 있습니다.


거의 2~3시간에 걸쳐서 작성한 것 같네요.

이것 보다 더 줄여서 만들 수도 있을 것 같은데 아무래도 줄이기가 힘드네요.

더 좋은 코드나 지적사항, 오탈자 지적이나 문의 사항 등 모두 댓글에 남겨주시면 시간 나는대로 답변 달아드리겠습니다.


어려운 분들은 여러번 읽어보고 직접 구현해보셔야해요.

그냥 쳐다보기만 해서는 이해하기 힘듭니다.

꼭 직접 구현해보세요!


현재 진행 상황은 http://kurien.dothome.co.kr에서 확인하실 수 있습니다!

TAG ,
  1. 이전 댓글 더보기
  2. hyeok 2015.10.09 13:25 신고  댓글주소  수정/삭제  댓글쓰기

    피드백 빠르시네요! 위의 파일 다운받아서 비교하여 문제 해결하였습니다. 감사합니다.

  3. pom30526 2015.10.09 20:10 신고  댓글주소  수정/삭제  댓글쓰기

    포스팅잘보고 있습니다.
    질문이 있는데 지금은 게시판이 한개만 운영하는게 기준이지만 실제적으로 여러개의 게시판을 운영할수도 있다고 생각합니다 .
    그러면 저 페이징 로직을 따로 떼서 include하는 방식으로 사용하는 건가요???
    더불어서 include방식으로 전환한다면 저로직이 function위주로 바뀌어서 새로 구성해야하는게 중복을 막는 성질이 강해지지 않나요? 궁금합니다.

    • Kurien 2015.10.10 08:41 신고  댓글주소  수정/삭제

      제가 적은것은 게시판 한개를 운영하는 기준이라기보다는 게시판 자체가 어떤식으로 구동되는건지에 대한 내용입니다.

      페이징 로직을 따로 떼서 사용하시던지 하나하나 일일히 만들던지 둘다 틀린답은 아닙니다.

      재사용성이 높은 코드가 더 좋다지만요,

    • 신기루 2015.11.11 15:18 신고  댓글주소  수정/삭제

      저는 일단 ASP 개발팀으로 근무를 했었는데 흠..
      말씀하시는 부분이 함수 호출하여 간단하게 리스트 및 페이징을
      사용하고 싶다 이말씀이신거죠??
      그렇다면 저 위의 코드를 함수 호출 형식으로 간단하게 쓰려면
      복잡해집니다. 보통 실무를 하다보면 저런 함수가 돌고 돕니다.
      위의 선배들이 보통 함수 호출하여 사용하지요.
      그렇다면..

      Call board('테이블명', '컬럼', '조건') 이런 형식으로
      짜맞추어진 함수를 찾으면 어딘가 있을 거에요.

      다만 지금 Kurien님은 게시판 형태의 로직을 이해시키려고
      게시판 형태 위주로 진행하신거구요.

      pom님이 함수 호출로 간단히 사용하시려면
      PHP 게시판 함수 호출 뭐 이런 키워드로 찾아보시는게
      더 빠를듯 합니다.

      다만 함수 호출 사용으로 하시기전에
      Kurien님의 게시판 형태 로직을 이해한다음 하시면 좋을 듯 싶네요.

  4. 현승혁 2016.02.12 01:50 신고  댓글주소  수정/삭제  댓글쓰기

    정말로 많은 도움 되었습니다 ㅎㅎ

  5. yada 2016.04.05 14:28 신고  댓글주소  수정/삭제  댓글쓰기

    맨 처음볼때 어렵고 이해안가고 그랬는데, 몇일동안 읽고 또읽고 또읽어보니
    하나하나 이해가 되고 있습니다. 정말 감사합니다!!

  6. 2pro 2016.07.08 10:27 신고  댓글주소  수정/삭제  댓글쓰기

    echo $paging 이 부분이 안나타 나는데 무슨 이유 일까여ㅜㅜ;;
    답답해서 두서 없이 질문하네요..
    중간중간 echo문 써서 변수 값을 확인했는데 제대로 잘 들어오더라구요
    근데 막상 index페이지로 가면 글 리스트가 안떠서 .. while문 위에 sql문을 다시 선언하고 index페이지 열면 그때서야 리스트가 나옵니다... 허나 페이징이 안되요 ㅜㅜ
    페이징을 직접 주소창에서 ?page=1 쓰면 그 땐 ' 처음1 2 3 4 끝' 이 나타나더라구요...
    구조는 거의 동일하나 제가 블로거님 소스에서 삭제한 부분은 date 부분 밖에 없습니다..
    while문 바로 위에 sql문을 작성하지 않으면 다음과 같은 에러가 발생해요..
    Fatal error: Call to a member function fetch_assoc() on boolean in C:\경로\phpfile.php on line 134
    134 line source : while($row=$result->fetch_assoc())

    html 시작 전
    $sqlLimit = 'limit' .$currentLimit. ',' .$onePage;

    $sql = 'select * from tablename order by columnname desc' .$sqlLimit;
    $result = $db->query($sql);

    while문 바로 위에 sql문을 재 선언해주면 문제가 될까요?

    • 2pro 2016.07.08 10:47 신고  댓글주소  수정/삭제

      질문 드리고 바로 해결했네여 ;;;
      근데 $sql문 선언 위치를 조금 바꿔봤습니다..
      $paging .='</ul>/; 페이징 끝 부분 부터
      ** 옮긴 부분 **
      $currentLimit ....

      ... $result = $db-> query($sql);
      ** 옮긴 부분 **

      이 부분을 html tbody while문(블로거님소스는 '$datetime = ' 이부분)바로 위 로 옮겼습니다.
      그러니 모든게 제대로 작동 되네여..
      위치를 옮김으로써 문제 될게 있을가요?ㅠㅠ

  7. 직딩1 2016.07.29 14:13 신고  댓글주소  수정/삭제  댓글쓰기

    안녕하세요. 벌써 페이징까지 왔네요... ^^

    페이징 기능은 무리없이 작동하는 것 같은데 페이징 번호가 세로로 나오고 옆에는 검은원모양도 나오고 있습니다. <li>태그 때문인 것 같은데 다 지우고 보니 에러가 나서 급히 복구했어요...

    그리고 b_no 말입니다만, 한 번 전체 데이터를 지우고 새 데이터를 넣었는데 1번부터 시작하지 않고 삭제한 데이터의 마지막 번호에 이어서 나오고 있습니다. 어디서 수정해야 할까요...?

    도움 부탁드립니다... ㅠㅠㅠ

    • Kurien 2016.07.30 12:56 신고  댓글주소  수정/삭제

      페이징이 세로로 나오는 이유는 li의 기본 특성때문입니다.

      float: left;와 관련된 css를 적용 하시면 정상적으로 출력되실껍니다.

      페이징 부분은 http://blog.kurien.co.kr/527#comment11507247 이곳의 댓글을 확인하시면 될 것 같습니다.

    • 직딩1 2016.08.01 18:58 신고  댓글주소  수정/삭제

      답변 감사합니다.
      다행히 수식은 옳게 한 것 같은데 그 수식을 for문에 적용하는 법을 몰라서요...
      index의 where을 for로 바꿔야할까요?

      ps. 제가 차단됐답니다. 좀 긴 댓글을 쓰려했는데 금칙어라도 포함됐나... ㅠㅠ

    • Kurien 2016.08.02 22:43 신고  댓글주소  수정/삭제

      만약 현재 페이지에서 보여야 할 번호가 16~25번이라 가정했을 때,

      for($i = {25}; $i >= 16; $i--) {
      리스트 출력
      }

      위와 같이 표현하시면 되겠습니다.

      그리고 차단되는 부분에 대해서는 제가 관리할 수 있는 부분이 아니라, 블로그측에서 차단하는거라서 제가 어떻게 할 수 있는 방법이 없을 것 같네요.

  8. ㅇㅅㅎ 2016.08.02 21:30 신고  댓글주소  수정/삭제  댓글쓰기

    저런식으로 만들면 처음하고 끝이 잘리는데.. 어떻게 해야할까요..

  9. thx 2016.08.05 14:10 신고  댓글주소  수정/삭제  댓글쓰기

    정말 감사드립니다 .!! 이틀 내내 고생했는데 이 글 보고 시원하게 해결 됐네요. 다른 글도 보고 도움 좀 받겠습니다 !

  10. ming 2017.02.13 16:38 신고  댓글주소  수정/삭제  댓글쓰기

    안녕하세요! 글 잘 보고 있습니다~
    질문이 하나 있는데.. 시간이 많이 지나서 답변을 받을 수 있을진 모르지만 남겨봅니다 ㅠㅠ

    if($page < 1 || $page > $allPage){
    ?>
    <script>
    alert("존재하지 않는 페이지입니다.");
    history.back();
    </script>
    <?php
    exit;
    }

    이 부분에서 포스팅하신 글대로라면 if 조건에 && 이 들어가야 하는데
    && 으로 넣으니까 페이징 작동 시 음수가 나옴 + alert도 뜨지 않더라구요,
    그래서 or 조건 (||)로 바꾸니까 제대로 alert이 뜨고 음수 페이지도 나타나지 않습니다.
    정확하게 &&이 맞는건가요 ||이 맞는건가요? ㅠㅠ

    • Kurien 2017.02.13 17:20 신고  댓글주소  수정/삭제

      말씀하신대로 ||(or 연산자)가 맞네요.

      제가 이 글을 작성했을 당시엔 한참 공부하던 상태라서 실수가 많이 있습니다.

      말씀해주신 내용으로 수정해두겠습니다!
      지적 감사합니다^^

      혹시 다른글에 대한 부분도 질문 있으시면 빠르게 답변해드릴테니 궁금한 점은 남겨주시면 감사하겠습니다.

  11. kuro 2017.02.20 17:10 신고  댓글주소  수정/삭제  댓글쓰기

    게시판이 처음만들어지면 글이 0인데

    $allPage까지 구했다면 $page가 1보다 작거나 $allPage보다 큰지 확인을 해봅니다.
    $page가 1보다 작거나 $allPage보다 클 수는 없으므로 이 경우는 사용자가 잘못된 경로를 이용한다는 뜻입니다.
    잘못된 경로이니 경고를 출력하고 이전 화면으로 돌려보내줍니다.

    이 구문 때문에 list페이지가 출력이 안됩니다.

    /* 페이징 끝 */
    $currentLimit = ($onePage * $page) - $onePage; //몇 번째의 글부터 가져오는지
    $sqlLimit = ' limit ' . $currentLimit . ', ' . $onePage; //limit sql 구문
    이 구문에서 if else로
    $page가 1보다 클때 아닐때를 구분해줘서

    아닐때는 첫페이지가 나오게 해야 되는거 아닌가요? ($currentLimit = ($page-1)*$onePage)

    그래야지 글이 없어도 리스트부분이 보이면서 글을 쓸 수 있는거 같은데...
    어렵네요... 게시판 만드는게

    • Kurien 2017.02.20 17:17 신고  댓글주소  수정/삭제

      말씀 하신 내용은 위 댓글에 해당하는 부분을 수정하면서 발생된 문제로 보이네요.

      if($page < 1 || $page > $allPage) {
      ....
      }

      if($page < 1 || ($allPage && $page > $allPage)) {
      ...
      }
      로 변경하면 될 것 같습니다.

      혹시나 또 다른 문제가 발생하셨다면 댓글 남겨주세요.

  12. kuro 2017.02.20 17:20 신고  댓글주소  수정/삭제  댓글쓰기

    답변 감사합니다.
    좋은 하루되세요!

  13. yo 2017.02.22 20:09 신고  댓글주소  수정/삭제  댓글쓰기

    if($page < 1 || ($allpage && $page > $allPage)) 위에는 이렇게 되어 있고..
    밑에는 if($page < 1 || $page > $allPage) 식으로 되어 있는데 .. 어떤것이 정답인가요??

  14. kuro 2017.03.08 00:40 신고  댓글주소  수정/삭제  댓글쓰기

    kurien님
    $currentSection = ceil($page / $oneSection); //현재 섹션
    firstPage = ($currentSection * $oneSection) - ($oneSection - 1); //현재 섹션의 처음 페이지
    현재 섹션이랑 현재 섹션의 처음페이지 구하는 공식이 이해가 잘 안돼요 ㅠ
    왜 저렇게 대입해서 구하는지 이해가 잘 안돼요 ㅠ.ㅠ
    이해 할 수 있게 쉽게 설명 해주시면 감사합니다.

    이거 이해하고 넘어 가야 되는거 같은데요..;;
    외워서 넘어가면 안되겠죠?
    나중에 쇼핑몰 아이템 리스트 뿌려줄때 같은 방법으로 하는거 맞나요?

    한가지 더 질문 좀 할께요
    kurien님 게시판에서
    http://kurien.dothome.co.kr/project/board/index.php?page=1

    여기서 page값을 10000000000000000000000000000000000000000000000000000000000000000 이렇게 아주 큰 숫자로 주면

    서버에 요청을 계속하다가
    Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 133431250 bytes) in /host/home3/kurien/html/project/board/index.php on line 84

    이 문구가 뜨면서 오류가 나는데요

    GET으로 받을 수 있는 숫자가 제한이 있는건가요?

    php스쿨 보면
    https://www.phpschool.com/gnuboard4/bbs/board.php?bo_table=qna_function&page=1

    여기에 페이지값을 100000000000000000000000000000000000000000000 크게 주면 값이 없게 나오는데, 서버요청은 계속하지 않더라고요

    제 웹서버 게시판은 무한로딩이고,제 카페24에 있는 게시판은 코드이그나이터로 만들었는데 무한로딩은 아니고 오류를 표시하네요

    • Kurien 2017.03.09 10:22 신고  댓글주소  수정/삭제

      제가 글에 적은 "현재 섹션"이란,

      총 100페이지 까지 있는 게시판이 있고 한 화면에 10 페이지($oneSection)씩 나타난다고 가정했을 때,

      1~10 페이지까지를 1개의 섹션으로 구분합니다.

      그럼 현재 페이지($page)의 위치가 4페이지라면 1섹션이고, 18페이지라면 2섹션이 되는거죠.
      100페이지라면 10섹션이 되는거구요.

      위의 내용을 수식화 한 것이 $page/$oneSection입니다.
      하지만 위와같이 나누게 되면 소수의 결과가 나타날 때가 있습니다.
      4페이지일 때 4/10 = 0.4처럼요.
      어짜피 1~10에선 모두 1섹션이므로 ceil(4/10)을 하여 모든 값을 "올림"처리 하게 됩니다.

      그럼 1~10까진 1섹션이 나오게 되는거죠.

      개발은 외워서 넘기시면 나중에도 그냥 따라하기밖에 못합니다.

      제 주관적인 생각에서는 이해하고 활용할 줄 아셔야 좋은 개발을 할 수 있을 것 같네요.

      쇼핑몰 아이템 리스트부분도 똑같은 방법이 맞습니다.

      대부분의 웹 프로그램은 CRUD(생성, 조회, 수정, 삭제)로 이루어져있고, 그 기본이 되는게 게시판이라고 생각합니다.

      게시판만 다른 도움 없이 제대로 만들줄 아신다면 다른 프로그램도 흐름이 어느정도 눈에 보이실겁니다.

      게시판 예제의 페이지 값을 높은 값으로 작업했을 때 나타나는 오류를 적어주셨는데, 오류만 봐서는 메모리 부족을 뜻하는 오류입니다.

      GET방식 자체의 길이 제한이라기보다는 예제가 존재하는 서버에 메모리 제한이라고 보시는 것이 편할 것 같습니다.

      메모리 부족이 일어나는 현상의 이유는 1.0E+15이상의 값이 들어올 경우 ceil함수에서 해당 값을 float 타입으로 변경하는데, float의 경우 1.0E+15이상의 값이 들어올 경우 값이 손실되어 $firstPage와 $lastPage의 값에 오류가 생깁니다.

      오류가 생긴 값이 for문에 입력되어 무한 반복되는 현상이 생기는 것 같습니다.

      위의 현상을 방지하기 위하여
      if($page < 1 || ($allPage && $page > $allPage)) {
      ?>
      <script>
      alert("존재하지 않는 페이지입니다.");
      history.back();
      </script>
      <?php
      exit;
      }
      라는 부분이 존재한다고 보시면 됩니다.

  15. kuro 2017.03.09 11:28 신고  댓글주소  수정/삭제  댓글쓰기

    너무 감사합니다.
    이해가 됐습니다.
    이제 안보고도 혼자 가능하네요 ㅠ
    오늘도 좋은 하루 되세요!

  16. hyo 2017.06.02 00:57 신고  댓글주소  수정/삭제  댓글쓰기

    혼자 학교과제로 인해서 시작했고 이 블로그를 통해 따라하게 되었습니다.
    꾸준히 따라하며 버벅거리지만 열심히 따라가는 중이었는데 페이징에서 막히게 되었어요ㅠㅠ
    메일로 제 코드와 궁금한점을 보냈습니다.
    도움 주시면 감사하겠습니다ㅜㅜ

  17. kim 2017.07.07 12:00 신고  댓글주소  수정/삭제  댓글쓰기

    초보인데 페이징공부중입니다
    코드를 전부작성했는데
    처음 1페이지에 모든 글이 보이면 어떻게수정해야될까요 ?

  18. 안녕하세요 2017.07.17 23:34 신고  댓글주소  수정/삭제  댓글쓰기

    덕분에 게시글 잘 보면서 따라해보고 있습니다 감사해요 ㅎㅎ 다름이아닐
    echo $paging;
    이 부분에서 제목에 없는 글을 검색하면 선언되지 않은 변수라고 자꾸 뜨네요.
    소스는 그대로 따라 쳤습니다 ㅠㅠ 뭐가 문제일까요?
    그리고 view.php?bno=<?php echo $row['b_no']?>" 이 부분 설명좀 부탁드릴게요 ㅠㅠ 해석이 잘 안되네요 ㅠㅠ

  19. hello 2017.07.29 17:27 신고  댓글주소  수정/삭제  댓글쓰기

    if($currentSection == $allSection) {
    $lastPage = $allPage; //현재 섹션이 마지막 섹션이라면 $allPage가 마지막 페이지가 된다.
    } else {
    $lastPage = $currentSection * $oneSection; //현재 섹션의 마지막 페이지
    }
    이부분에서 마지막 페이지가 출력되지않아
    $lastPage = $allPage +1;
    $lastPage = $currentSection * $oneSection +1; 각각1씩 더하니 정상 출력되었습니다.

  20. 이순미 2018.11.05 21:17 신고  댓글주소  수정/삭제  댓글쓰기


    ◈아가씨 100명 출근-유흥No.1 리얼 맞춤 초이스 최대물량!최강수질!최저 가격

    ◈전국 지역 24 시간 원하는시간에 어디든지 달려가겠습니다 !!

    ◈신뢰와 정직을 바탕으로 거짓없는 마음으로 모시겠습니다

    ◈정해진시간동안무한횟수 노콘.입사.질사.후장.SM.삿가시...

    ◈믿고 찾아주신다면 무조건!말그대로 무조건됩니다!!

    ◈오빠들의 유흥을 더욱더 화끈하고 짜릿하게 만들어 드릴것을 약속드립니다

    ◈홈페이지: www.bam01.com

    ◈ka talk : sg8888

    ◈최고의 서비스 최하의 가격으로 모십니다.

  21. 이순미 2018.11.07 23:39 신고  댓글주소  수정/삭제  댓글쓰기


    ◈아가씨 100명 출근-유흥No.1 리얼 맞춤 초이스 최대물량!최강수질!최저 가격

    ◈전국 지역 24 시간 원하는시간에 어디든지 달려가겠습니다 !!

    ◈신뢰와 정직을 바탕으로 거짓없는 마음으로 모시겠습니다

    ◈정해진시간동안무한횟수 노콘.입사.질사.후장.SM.삿가시...

    ◈믿고 찾아주신다면 무조건!말그대로 무조건됩니다!!

    ◈오빠들의 유흥을 더욱더 화끈하고 짜릿하게 만들어 드릴것을 약속드립니다

    ◈홈페이지: www.bam01.com

    ◈ka talk : sg886

    ◈최고의 서비스 최하의 가격으로 모십니다.