안녕하세요, 개발자 Demain입니다. 이번글에서는 PHP를 사용해서 게시판 페이징을 구현하는 방법에 대해서 알아보도록 하겠습니다.

기술스택

  • PHP
  • Codeigniter
  • Mysql
  • Apache

개발

일단 페이징을 구현하기 전에 정해야 할게 있습니다

  1. 한 페이지에 보여줄 게시물 갯수
  2. 최대 페이지 번호

1번은 페이지 이동시 보여줄 게시물의 최대 출력 갯수를 의미하며 2번은 이동할 수 있는 페이지 번호를 최대 몇번까지 보여줄지 정하는 것 입니다. 저는 1번은 최대 5개, 2번은 최대 10개로 설정하도록 하겠습니다.

가장 먼저 할일은 게시물로 쓰일 더미 데이터 테이블을 만드는 일입니다. 테이블 이름은 posts, 테이블 구조는 아래와 같이 설정하겠습니다.

CREATE  TABLE  `posts` (
`number`  int(11) NOT  NULL,
`category`  text  NOT  NULL,
`title`  text  NOT  NULL,
`title_eng`  text  NOT  NULL,
`sub_title`  text  NOT  NULL,
`tags`  text  NOT  NULL,
`date`  text  NOT  NULL,
`uploader`  text  NOT  NULL,
`main_text`  text  NOT  NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='post all database table';

그리고 여기에 쓰일 더미데이터를 생성하겠습니다.

enter image description here

이제 데이터베이스는 준비가 끝났고 로직을 개발해야할 차례입니다. 위에서 언급했듯이 언어는 PHP를, 프레임워크는 Codeingniter(줄여서CI)를 사용하도록 하겠습니다. CI는 MVC 디자인 패턴의 프레임워크로 컨트롤러모델, 로 나누어져 있는 구조입니다. 클라이언트쪽에서 데이터를 받으면 컨트롤러에서 필터링을 시키고 모델을 거쳐 값을 도출하며 그 값을 에서 출력하는 방식의 프레임워크입니다. 자세한 설명은 생활코딩의 이글을 참고하세요.

라우팅(Routing)

페이징을 구현할때 URL을 작성하는 방식은 크게 두가지로 나누어 집니다.
localhost/?page=1&limit=5와 같이 GET을 사용해 뷰단 자체에서 페이징을 구현하는것과
localhost/list/1 프레임워크에 내장된 라우팅 함수를 사용해 주소를 통해 페이징을 사용하는 방법으로 나누어져 있습니다.

이번 글에서는 두번째 방식을 사용해서 페이징을 구현하도록 하겠습니다. 또한 CI에서는 config.php라는 라우팅 설정파일을 자체적으로 지원하기 때문에 이를 사용하도록 하겠습니다

config.php

<?
$route['default_controller']  =  'main/about';
// 아무런 조작이 없으면 about페이지를 topic컨트롤러의 index로 설정한다
$route['404_override']  =  'main/notfound';
$route['translate_uri_dashes']  =  FALSE;

$route['list']  =  "main/index_list/1";
// localhost/list -> main/index_list/1
$route['list/(:any)']  =  "main/index_list/$1";
// localhost/list/주소값 -> main/index_list/주소값
?>

컨트롤러

<?
function  index_list($request)
// localhost/list/$request -> index_list($request)
// 여기서 $request란 페이지 번호 값이다
{

$data['css']  =  'index';
$data['num']  =  $request;
if  ($request  ==  1)  {
$db_req[0]  =  0;
$db_req[1]  =  $request+4;
}  else  {
// $request값이 1 이상일 경우 ex) $request = 2
$num  =  $request  -  1;
// $num = 1
$num  =  $num  *  5;
// $num = 5
$db_req[0]  =  $num;
// $db_req[0] = 5
$db_req[1]  =  $request+5;
// $db_req[1] = 10
} 

$this->load->model('Post_model');
$post_all  =  $this->Post_model->post_require_all();
$post  =  $this->Post_model->post_require_paging($db_req);
// 생성한 배열인 $db_req[]를 post_require_paging 모델로 전송

$this->load->view('Header-ex',  $data);
$this->load->view('Index_paging',  array('post'=>$post,  'post_all'=>$post_all));
// 그다음 돌아온 값을 배열로 만들어 뷰인 Index_paging에 전송
$this->load->view('Footer');

}
?>

모델

<?
public  function  post_require_paging($db_req)
{

return  $this->db->query("
SELECT  *  FROM `posts` 
ORDER BY `number` 
DESC  Limit  $db_req[0], $db_req[1]
")->result();
// db를 연결해 query문을 요청하고 그 값을 result_array로 받은 후 $this에 저장
// 이후 이값은 다시 컨트톨러로 올라감

}
?>

<?
if  (empty($post))
// $post값이 비어있는지 검사, 참이라면 if문 실행
{
	echo  '
	<div class="post post-no">
	<div class="info">
	</div>
	<div class="post-content">
	<p class="sub-txt" style="text-align: left; margin-top: 10px;">이 카테고리에 작성된 글이 없습니다.</p>
	</div>
	</div>
	';
}
else
{
	// $post값이 비어있지 않다면 foreach문 실행, 
	foreach($post  as  $list)
	{
		echo  '
		<div class="post post-'.$list->number.'">
		<div class="info">
		<div class="date">'.$list->date.' '.$list->uploader.'</div>
		<div class="uploader"></div>
		</div>
		<div class="post-content">
		<a href="/'.$list->title_eng.'">
		<p class="txt">
		'.$list->title.'
		</p>
		<p class="sub-txt">
		'.$list->sub_title.'
		</p>
		</a>
		</div>
		</div>
		';
	}
}
?>

<div  class="paging">

<?
$len  =  '';

foreach($post_all  as  $list):
$len  =  $len.$list->number;
// 모든 게시물의 갯수를 받아와서 $len에 저장
endforeach;

$count  =  strlen($len)  /  5;
// 게시물의 갯수를 5로 나눈다
$page_count  =  ceil($count);
// 반올림해서 page_count에 저장
$strTok  =  explode('/'  , uri_string());
// 현재 페이지의 url을 /를 기준으로 나눈다
$page_now  =  $strTok[1];
// 페이지 번호(2페이지라면 값은 2)를 $page_now에 저장
if  ($page_now  ==  1) 
{
	echo  '';
}
else 
{
	$page_move  =  $page_now  -  1;
	echo  '<a href="/list/'.$page_move.'"><span class="hover"><i class="material-icons icon-prev">keyboard_arrow_left</i>Prev</span></a>';
}
// 페이지가 1번일때는 pass, 그 외의 경우에는 뒤로가기 버튼 생성

echo  '&nbsp;&nbsp;<span>';
for  ($i=1;  $i  <=  $page_count;  $i++) 
{
	echo  '<a href="/list/'.$i.'" class="paging-num">'.$i.'&nbsp;';
}
// 페이지 갯수만큼 바로가기 버튼 생성
echo  '<span>&nbsp;';
if($page_count  ==  $page_now) 
{
	echo  '';
}
else  if  ($page_count  >  1) 
{
	$page_move  =  $page_now  +  1;
	echo  '<a id="btn-next" href="/list/'.$page_move.'"><span class="hover">Next<i class="material-icons icon-next">keyboard_arrow_right</i></span></a>';
}
// 마지막 페이지 번호인 page_count와 현재 페이지 번호인 page_now를 대조해서 참이 pass, 참이 아니라면 앞으로가기 버튼 생성

?>
</div>

결과

localhost/list/1

enter image description here
2또는 Next클릭시

localhost/list/2
enter image description here
위와같이 출력됩니다.