SKILL/LARAVEL

일반 php로 알아보는 페이지나누기 원리!

Jedy_Kim 2017. 11. 23. 19:18
728x90

글 목록


필요요소

1. 글의 번호

주로 글의 순서를 인지시키고자 하는 용도와 "몇 번 글" 이라는 게시물을 구분짖는 용도 등으로 사용된다.

글의 번호는 일반적으로 게시물이 등록된 순서이며 중간에 삭제된 글이 있다면 삭제된 글을 무시한 번호이다.

즉, 우리가 글을 구분짓고자 사용하는 id 값과 글의 번호는 실질적으로 같지 않음. 


2. 글의 제목


3. 글쓴이


4. 글 쓴 날짜


5. 조회 수


위와 같은 항목을 목록으로 보여주는 쿼리문

SELECT * FROM board ORDER BY id DESC

이 쿼리를 사용하면 쉽게 가져올 수 있으나 문제는 100개, 1000개의 글을 한 페이지에 모두 출력해야하는 문제

10 개씩 가져오는 쿼리문

SELECT * FROM board ORDER BY id DESC LIMIT 0, 10;


결과가 여러 개가 검색되는 경우

while ($row=mysqli_fetch_array($result)) {

echo $row[id];

echo $row[name];

echo $row[title];

echo $substr($row[wdate], 0, 10);

}



페이지네이션시 고려사항


1. 현재 페이지는 몇 번째 페이지인가?

2. 현재 페이지는 몇 번 페이지부터 시작하는가?

3. 현재 페이지는 몇 번 페이지까지 출력하는가?

4. 10개를 출력하였다면 그 이후의 페이지가 더 존재하는가?

5. 첫 번째 출력된 페이지 번호보다 작은 페이지가 존재하는가?

6. 현재 페이지의 첫 번째 글은 몇 번의 글인가?


페이지에 대한 정의


$no 페이지가 시작되는 첫 글의 순번

$page_size 한 페이지당 보여줄 게시물의 수

$page_list_size 페이지 리스트에 보여줄 페이지의 수

$total_row 총 게시물의 수

$total_page 총 페이지 수

$current_page 현재 페이지 (0부터 시작)

$start_page 페이지 리스트에서 첫 번째 페이지 (0부터 시작)

$end_page 페이지 리스트에서 마지막 페이지 (0부터 시작)

$prev_list 이전 페이지 리스트

$next_list 다음 페이지 리스트 


$no

10씩 증가하는 값을 갖는다.

1, 2..가 아닌 10씩 증가하는 이유?

$no 변수가 페이지 번호를 가리키는 것이 아니라 그 페이지의 첫 번째 글의 순서를 가리키기 때문.

여기서 주의할 점은 글의 번호(id)가 아니라 검색된 글의 순서이다.

즉, $no 변수가 0이라면 앞서 만든 쿼리에서 검색된 결과의 첫 번째 행이 이 페이지의 첫 번째 글이 된다는 의미.

만약 $no 변수값이 10이라면 검색된 결과 중 11번째(0부터 시작했으므로)에 존재하는 글이 페이지의 첫 번째 글이 됨을 의미한다.

결론 1페이지는 10, 2페이지는 20의 값을 가지게 됨.


$no 값은 특별히 지정되어 있지 않은데 값이 지정되지 않았으면 첫 번째 페이지 즉, $no 값이 0임을 의미한다.

http://도메인/board/list.php?no=0 이라고 입력하게 하는 귀찮음을 덜어주기 위해 다음과 같은 코드를 사용한다.


if (!no || $no < 0 ) $no = 0; //$no 값이 안 넘어오거나 음수값이 넘어오는 경우 0


$no란 값이 왜 생겼는지는 목록을 뿌려주는 쿼리와 연관이 있다.

총 100개의 글중 10개만 뿌려주고 싶어서 LIMIT 0, 10을 사용했으나, 문제는 두 번째, 세 번째 모든 페이지가 0~9번까지만 보임. 결국 LIMIT 0, 10 의 0값을 매번 다르게 설정해주어야함.

첫 페이지는 10번이, 두 번째 페이지는 20번이...첫 글이 됨.

그래서 $no 값이 생겼음. 즉 LIMIT $no, 10으로 바뀌면 페이지별로 10개씩의 글을 검색해 올 수 있음.


$page_size

이 변수의 경우 페이지 나누기에 꼭 필요하지 않으나 한 페이지에 보여주고 싶은 게시글의 수를 정하려고 만들어짐.

일괄적으로 수정하면 가능하겠지만 보다 손쉽게 수정하기 위해 만들어진 변수

SELECT * FROM boar ORDER BY id DESC LIMIT $no, $page_size


$total_row

페이지 목록을 나누려면 우선 총 게시물의 숫자를 알아야한다. 그래야만 한 페이지당 표시할 글의 수($page_size)를

통해서 총 몇 개의 페이지가 존재하는지 계산할 수 있기때문.


총 게시물의 수 : SELECT count(*) FROM board


$result_count = mysqli_query($connect, "SELECT count(*) FROM board");

$result_row = mysqli_fetch_row($result_count);

$total_row = $result_row[0];


mysql_fetch_array 함수를 사용하여 $count_row 변수에 배열로 저장 시 문제점

$count_row[count(*)]..count(*)는 컬럼의 이름이 아님.

그래도 사용하고 싶을 경우

SELECT COUNT(*) as total FROM board;


$count_row[total]과 같은 방식으로..


$total_page 

총 페이지의수를 저장하는 변수로 'ceil(총 게시물의 수/한 페이지에 출력되는 글의 수)' 를 나눠준다.

올림하는 이유는 게시물이 1개만 더 있더라도 한 페이지가 추가되기 때문.


$current_page

현재 페이지는 $no 변수와 $page_size를 통해서 구할 수 있다. 

$no 변수를 통해서 현재 페이지의 첫 번째 글이 검색 결과 중 몇 번째 글인지 알 수 있음.

여기에 총 페이지로 나누어서 몇 번째 페이지인지 구할 수 있다.


$current_page = ceil(($no+1)/$page_size);


$total_row값은 1부터 시작하는 값이지만 $no 변수는 0부터 시작하는 값이기 때문 $no +1을 해줘야 같은 공식을 사용가능. 


$start_page

여기서 페이지의 목록의 수를 조절할 수 있게 하고자 $page_list_size 라는 변수를 추가

$page_list_size 변수를 조절하여 목록에 표시되는 수를 조절함.


$start_page = floor(($current_page - 1) / $page_list_size)*$page_list_size + 1;


$start_page가 1, 11, 21과 같은 값을 원함. 그래서 floor부분은 0, 1, 2와 같은 식으로 증가하고 거기에 페이지 목록의 수인 10이 곱해지고 +1이 되어 1, 11, 21..이 됨.


$end_page

마지막 페이지는 두 가지로 나누어짐

1) 페이지가 아지가 많이 남아 있어서 $page_list_size만큼을 채우는 경우

$end_page = $start_page + $page_list_size -1;

2) 페이지가 $page_list_size만큼 없어서 모자라게 출력되는 경우

if($total_page < $end_page) $end_page = $total_page;


$prev_list

목록 이전의 페이지로 넘어가려면 반드시 현재의 페이지가 적어도 2번째 목록 페이지에 있어야 한다.

만약 페이지 목록의 크기보다 시작 페이지의 번호가 클 경우 분명히 이전에 페이지 목록이 존재할 것이다.


if ($start_page > $page_list_size) {

//이전 페이지 목록이 존재함

}


또한 페이지 정보는 $no 변수를 통해 이루어지므로 이전 페이지로 돌아가는 것은 $no 값의 변화로 수정해야 한다.

$no 값은 항상 $page_size 값의 배수이다.

목록을 시작하는 페이지의 $no = ($start_page - 1) * page_size;


한 페이지 이전의 $no 값 -> $prev_list = ($start_page - 2 ) * $page_size;


if ($start_page > $page_list_size) {

$prev_list = ($start_page-2) * $page_size;

echo "<a href="\"$PHP_SELF?no=$prev_list\"><<</a>\n";

}

페이지 페이지당 게시물 번호

1 - 0~9

2 - 10~19

3 - 20~29

    ...

10 - 90~99

///////////////////

11 - 100~110

<<11...20>>


페이지 리스트 출력

for ( $i = $start_page; $i <= $end_page; $i++) {

$page = ($i-1) * $page_size; //페이지 값을 $no 값으로 표시

if ( $no != $page ) { //현재 페이지가 아닐 경우에만 링크를 표시

echo "<a href=\"$PHP_SELF?no=$page\">";

}

echo "$i"; //페이지를 표시

if ($no != $page ) {

echo "</a>";

}

}


$next_list

다음 페이지 리스트가 필요할 때는 총 페이지가 마지막 리스트의 페이지보다 클 때.

리스트를 다 뿌리고도 더 뿌려줄 페이지가 남았을 경우 다음 버튼이 필요.


현재 페이지에서 다음 페이지의 $no 값은 다음과 같이 표시됨


$current_page / $page_size;


(($current-1) * $page_size 가 $no 값으로 변환하므로..)


if ($total_page > $end_page ) {

$next_list = $end_page * $page_size; 200

echo "<a href=\"$PHP_SELF?no=$next_list\">>></a>";100

}


1 - 0~9

2 - 10~19

3 - 20~29

...

10 - 90~99

11 = 100~110

<<11...20>>

21 - 200~210

<<21...30>>


반응형

'SKILL > LARAVEL' 카테고리의 다른 글

블레이드  (0) 2017.11.25
뷰와 데이터 바인딩  (0) 2017.11.21
라우팅  (0) 2017.11.21
라라벨 설치  (0) 2017.11.21
개발 환경 준비-for MAC  (0) 2017.11.21