-
[CodeIgniter] 4. 게시판 프로젝트 - DB 설계, 페이징 처리Web/CodeIgniter 2015. 8. 21. 19:24
지금까지 CodeIgniter 개발 환경을 구성하고 기본 구조에 대해 알아봤습니다.
4장은 MySQL 테이블을 구성하고 게시판을 실제로 만들어 보면서 CodeIgniterd의 MVC 패턴 사용방법과 컨트롤러의 몇 가지 유형을 알아봅니다.
게시판은 하나의 테이블로 원 글과 댓글을 표현하는 구조이며 리스트, 검색, 페이징, 상세보기, 쓰기, 수정, 삭제로 이루어져 있습니다.
개발을 할 때 제일 먼저 시작하는 작업인 테이블 만들기부터 시작합시다.
4.1 게시판 테이블 만들기
ci_book 데이터베이스를 생성하고 MySQL 콘솔에 접속합니다.
mysqladmin -uroot -p create ci_book
mysql -uroot -p ci_book
grant select, insert, update, delete, create, alter, drop on ci_book .* to 'book_user'@'localhost' identified by 'book_password';
데이터베이스를 생성하고 사용자를 생성했습니다. 이제 테이블을 만들어보겠습니다.
ci_board 테이블
int board_id
int board_pid
varchar user_id
varchar user_name
varchar subject
text contents
int hits
date reg_date
MySQL 콘솔 명령어
use ci_book
CREATE TABLE ci_board (
board_id int(10) NULL AUTO_INCREMENT PRIMARY KEY,
board_pid int(10) NULL DEFAULT 0 COMMENT '원글 번호',
user_id varchar(20) COMMENT '작성자ID',
user_name varchar(20) NOT NULL COMMENT '작성자 이름',
subject varchar(50) NOT NULL COMMENT '게시글 제목',
contents text NOT NULL COMMENT '게시글 내용',
hits int(10) NOT NULL DEFAULT 0 COMMENT '조회수',
reg_date datetime NOT NULL COMMENT '등록일',
INDEX board_pid (board_pid)
)
COMMENT='CodeIgniter 게시판'
COLLATE='utf8_general_ci'
ENGINE=MyISAM;
show tables;
desc ci_board;
마지막 명령어를 통해 ci_board의 구조를 확인함으로써, 데이터베이스 생성, 사용자 생성 및 권한주기, 테이블 생성이 끝났습니다.
4.2 목록 보기 기능 만들기
이번 절에서는 4.1절에서 생성한 테이블에 가상 데이터를 넣고 그 내용을 불러오는 프로그램을 만들어 보겠습니다.
먼저 화면에 리스트만 뿌리고 그 다음에 페이징을 붙이고 검색기능을 추가하겠습니다.
4.2.1 리스트 불러오기
먼저 MySQL에 가상 데이터를 입력하도록 하겠습니다.
INSERT INTO ci_board(user_id, user_name, subject, contents, hits, reg_date) VALUES ('advisor', 'Palpit', 'First Note', 'Test', 0, '2015-08-11 11:11:21');
INSERT INTO ci_board(user_id, user_name, subject, contents, hits, reg_date) VALUES ('advisor', 'Palpit', 'Second Note', 'Test', 0, '2015-08-11 11:11:21');
INSERT INTO ci_board(user_id, user_name, subject, contents, hits, reg_date) VALUES ('advisor', 'Palpit', 'Third Note', 'Test', 0, '2015-08-11 11:11:21');
INSERT INTO ci_board(user_id, user_name, subject, contents, hits, reg_date) VALUES ('advisor', 'Palpit', 'Fourth Note', 'Test', 0, '2015-08-11 11:11:21');
INSERT INTO ci_board(user_id, user_name, subject, contents, hits, reg_date) VALUES ('advisor', 'Palpit', 'Fifth Note', 'Test', 0, '2015-08-11 11:11:21');
INSERT INTO ci_board(user_id, user_name, subject, contents, hits, reg_date) VALUES ('advisor', 'Palpit', 'Sixth Note', 'Test', 0, '2015-08-11 11:11:21');
INSERT INTO ci_board(user_id, user_name, subject, contents, hits, reg_date) VALUES ('advisor', 'Palpit', 'Seventh Note', 'Test', 0, '2015-08-11 11:11:21');
INSERT INTO ci_board(board_pid, user_id, user_name, subject, contents, hits, reg_date) VALUES (1, 'zhfldi4', 'Cyzone', 'Comment Test', 'Comment', 0, '2015-08-12 23:11:11');
INSERT INTO ci_board(board_pid, user_id, user_name, subject, contents, hits, reg_date) VALUES (1, 'zhfldi4', 'Cyzone', 'Comment Test2', 'Comment', 0, '2015-08-12 23:11:11');
입력된 데이터를 확인하기 위해 아래 명령어를 입력합니다.
SELECT * FROM ci_board;
목록에서 불러올 가상 데이터가 준비되었으니 소스 코딩을 해보겠습니다. 먼저 컨트롤러를 작성합니다.
(todo 프로젝트와 마찬가지로 bbs 폴더를 생성하여 CodeIgniter를 복사해서 환경을 구성해주세요)
* board.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748<?phpif (!defined('BASEPATH'))exit('No direct script access allowed');/*** 게시판 메인 컨트롤러*/class Board extends CI_Controller {function __construct() {parent::__construct();$this -> load -> database();$this -> load -> model('board_m');$this -> load -> helper(array('url', 'date'));}/*** 주소에서 메서드가 생략되었을 때 실행되는 기본 메서드*/public function index() {$this -> lists();}/*** 사이트 헤더, 푸터가 자동으로 추가된다.*/public function _remap($method) {// 헤더 include$this -> load -> view('header_v');if (method_exists($this, $method)) {$this -> {"{$method}"}();}// 푸터 include$this -> load -> view('footer_v');}/*** 목록 불러오기*/public function lists() {$data['list'] = $this -> board_m -> get_list();$this -> load -> view('board/list_v', $data);}}cs 모델을 이용하려면 데이터베이스에 연결해야 하는데 그 부분은 application/config/database.php 에 4.1절에서 만든 사용자, 비밀번호, HOST, 데이터베이스 명을 입력하고 자동로딩 라이브러리 부분에 데이터베이스를 선언하여 사용합니다.
* bbs/application/config/database.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');/*| -------------------------------------------------------------------| DATABASE CONNECTIVITY SETTINGS| -------------------------------------------------------------------| This file will contain the settings needed to access your database.|| For complete instructions please consult the 'Database Connection'| page of the User Guide.|| -------------------------------------------------------------------| EXPLANATION OF VARIABLES| -------------------------------------------------------------------|| ['hostname'] The hostname of your database server.| ['username'] The username used to connect to the database| ['password'] The password used to connect to the database| ['database'] The name of the database you want to connect to| ['dbdriver'] The database type. ie: mysql. Currently supported:mysql, mysqli, postgre, odbc, mssql, sqlite, oci8| ['dbprefix'] You can add an optional prefix, which will be added| to the table name when using the Active Record class| ['pconnect'] TRUE/FALSE - Whether to use a persistent connection| ['db_debug'] TRUE/FALSE - Whether database errors should be displayed.| ['cache_on'] TRUE/FALSE - Enables/disables query caching| ['cachedir'] The path to the folder where cache files should be stored| ['char_set'] The character set used in communicating with the database| ['dbcollat'] The character collation used in communicating with the database| NOTE: For MySQL and MySQLi databases, this setting is only used| as a backup if your server is running PHP < 5.2.3 or MySQL < 5.0.7| (and in table creation queries made with DB Forge).| There is an incompatibility in PHP with mysql_real_escape_string() which| can make your site vulnerable to SQL injection if you are using a| multi-byte character set and are running versions lower than these.| Sites using Latin-1 or UTF-8 database character set and collation are unaffected.| ['swap_pre'] A default table prefix that should be swapped with the dbprefix| ['autoinit'] Whether or not to automatically initialize the database.| ['stricton'] TRUE/FALSE - forces 'Strict Mode' connections| - good for ensuring strict SQL while developing|| The $active_group variable lets you choose which connection group to| make active. By default there is only one group (the 'default' group).|| The $active_record variables lets you determine whether or not to load| the active record class*/$active_group = 'default';$active_record = TRUE;$db['default']['hostname'] = 'localhost';$db['default']['username'] = 'book_user';$db['default']['password'] = 'book_password';$db['default']['database'] = 'ci_book';$db['default']['dbdriver'] = 'mysql';$db['default']['dbprefix'] = '';$db['default']['pconnect'] = FALSE;$db['default']['db_debug'] = TRUE;$db['default']['cache_on'] = FALSE;$db['default']['cachedir'] = '';$db['default']['char_set'] = 'utf8';$db['default']['dbcollat'] = 'utf8_general_ci';$db['default']['swap_pre'] = '';$db['default']['autoinit'] = TRUE;$db['default']['stricton'] = FALSE;/* End of file database.php *//* Location: ./application/config/database.php */cs 이제 컨트롤러에서 로딩한 모델과 뷰에 대해 알아보도록 하겠습니다.
* bbs/application/models/board_m.php
12345678910111213141516171819202122232425<?phpif (!defined('BASEPATH'))exit('No direct script access allowed');/*** 공통 게시판 모델*/class Board_m extends CI_Model {function __construct() {parent::__construct();}function get_list($table = 'ci_board') {$sql = "SELECT * FROM ".$table." ORDER BY board_id DESC";$query = $this -> db -> query($sql);$result = $query -> result();// $result = $query->result_array();return $result;}}cs Line 18: 위 라인처럼 결과를 리턴하면 $result->board_id 형태로 값을 사용할 수 있고, Line 19처럼 결과를 리턴하면 $result['board_id'] 형태로 사용할 수 있습니다.
이제 뷰 파일의 내용을 살펴보도록 하겠습니다. 컨트롤러에서 선언한 내용은 'board/list_v' 입니다. .php 확장자는 생략합니다.
CodeIgniter에서 확장자를 자동으로 붙여서 찾아줍니다.
게시판 프로젝트에서는 헤더와 푸터를 나눠서 사용합니다.
* bbs/application/views/header_v.php
12345678910111213141516171819202122232425262728<!DOCTYPE html><html><head><meta charset="UTF-8"/><meta name="apple-mobile-web-app-capable" content="yes" /><meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" /><title>CodeIgniter</title><script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script><link type="text/css" rel='stylesheet' href="/todo/include/css/bootstrap.css" /></head><body><div id="main"><header id="header" data-role="header" data-position="fixed"><blockquote><p>만들면서 배우는 CodeIgniter</p><small>실행 예제</small></blockquote></header><nav id="gnb"><ul><li><a rel="external" href="/bbs/<?php echo $this -> uri -> segment(1); ?>/lists/<?php echo $this -> uri -> segment(3); ?>"> 게시판 프로젝트 </a></li></ul></nav>cs * bbs/application/views/board/list_v.php
123456789101112131415161718192021222324252627282930313233343536<article id="board_area"><header><h1></h1></header><h1></h1><table cellpadding="0" cellspacing="0"><thead><tr><th scope="col">번호</th><th scope="col">제목</th><th scope="col">작성자</th><th scope="col">조회수</th><th scope="col">작성일</th></tr></thead><tbody><?phpforeach($list as $lt){?><tr><th scope="row"><?php echo $lt -> board_id;?></th><td><a rel="external" href="/bbs/<?php echo $this -> uri -> segment(1); ?>/view/<?php echo $this -> uri -> segment(3); ?>/<?php echo $lt -> board_id; ?>"> <?php echo $lt -> subject;?></a></td><td><?php echo $lt -> user_name;?></td><td><?php echo $lt -> hits;?></td><td><time datetime="<?php echo mdate("%Y-%M-%j", human_to_unix($lt -> reg_date)); ?>"><?php echo mdate("%Y-%M-%j", human_to_unix($lt -> reg_date));?></time></td></tr><?php}?></tbody></table></article>cs * bbs/application/views/footer_v.php
123456789101112131415<footer id="footer"><dl><dt><a class="azubu" href="http://www.cikorea.net/" target="blank"> CodeIgniter 한국 사용자포럼 </a></dt><dd>Copyright by <em class="black">Palpit</em>.</dd></dl></footer></div></body></html>cs 코딩은 HTML5 이며 헤더, 콘텐츠, 푸터 세 부분으로 나뉘어 있습니다.
헤더, 푸터를 모든 페이지에 넣으면 수정사항이 생겼을 시에 일일이 모든 페이지를 수정해야 합니다. 그래서 CodeIgniter의 _remap() 메서드를 이용해 자동으로 헤더와 푸터를 선언합니다. 그래서 뷰에는 헤더, 푸터를 제외한 나머지 콘텐츠 부분만 들어갑니다.
4.2.2 페이징 만들기
이번 절에서는 게시판의 중요한 기능 중 하나인 페이징을 구현하도록 하겠습니다.
pagination 라이브러리는 주소의 page 변수와 연계해 이동 가능한 링크를 만듭니다. 이동 가능한 링크와 연계되게 모델에서 데이터를 가져오는 부분이 변경되며, 전체 게시물 수를 체크하는 등 추가해야 할 작업이 많습니다.
처음에는 이해하기 힘들 수 있는데 페이징은 정형화된 형태라서 두고두고 그대로 사용할 수 있습니다.
페이징을 구현하는 컨트롤러 소스를 살펴보도록 하겠습니다.
* bbs/application/controllers/board.php
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677<?phpif (!defined('BASEPATH'))exit('No direct script access allowed');/*** 게시판 메인 컨트롤러*/class Board extends CI_Controller {function __construct() {parent::__construct();$this -> load -> database();$this -> load -> model('board_m');$this -> load -> helper(array('url', 'date'));}/*** 주소에서 메서드가 생략되었을 때 실행되는 기본 메서드*/public function index() {$this -> lists();}/*** 사이트 헤더, 푸터가 자동으로 추가된다.*/public function _remap($method) {// 헤더 include$this -> load -> view('header_v');if (method_exists($this, $method)) {$this -> {"{$method}"}();}// 푸터 include$this -> load -> view('footer_v');}/*** 목록 불러오기*/public function lists() {$this -> load -> library('pagination');// 페이지 네이션 설정$config['base_url'] = '/bbs/board/lists/ci_board/page';// 페이징 주소$config['total_rows'] = $this -> board_m -> get_list($this -> uri -> segment(3), 'count');// 게시물 전체 개수$config['per_page'] = 5;// 한 페이지에 표시할 게시물 수$config['uri_segment'] = 5;// 페이지 번호가 위치한 세그먼트// 페이지네이션 초기화$this -> pagination -> initialize($config);// 페이지 링크를 생성하여 view에서 사용하 변수에 할당$data['pagination'] = $this -> pagination -> create_links();// 게시물 목록을 불러오기 위한 offset, limit 값 가져오기$page = $this -> uri -> segment(5, 1);if ($page > 1) {$start = (($page / $config['per_page'])) * $config['per_page'];} else {$start = ($page - 1) * $config['per_page'];}$limit = $config['per_page'];$data['list'] = $this -> board_m -> get_list($this -> uri -> segment(3), '', $start, $limit);$this -> load -> view('board/list_v', $data);}}cs Line 44: pagiation을 이용하기 위해 라이브러리를 로딩합니다.
Line 47: pagination 라이브러리 설정 중에서 선언하지 않으면 에러가 날 수 있는 설정입니다.
다음으로 바뀐 모델의 소스는 아래와 같습니다.
* bbs/application/models/board_m.php
123456789101112131415161718192021222324252627282930313233343536<?phpif (!defined('BASEPATH'))exit('No direct script access allowed');/*** 공통 게시판 모델*/class Board_m extends CI_Model {function __construct() {parent::__construct();}function get_list($table = 'ci_board', $type = '', $offset = '', $limit = '') {$limit_query = '';if ($limit != '' OR $offset != '') {// 페이징이 있을 경우 처리$limit_query = ' LIMIT ' . $offset . ', ' . $limit;}$sql = "SELECT * FROM " . $table . " ORDER BY board_id DESC " . $limit_query;$query = $this -> db -> query($sql);if ($type == 'count') {$result = $query -> num_rows();} else {$result = $query -> result();}return $result;}}cs 모델 부분에서는 페이징 관련 파라미터가 있을 때의 처리와 두 번째 파라미터가 'count' 일때의 처리가 추가되었습니다.
페이징 연동 링크를 만들고 페이지와 연결된 데이터를 가져와서 뷰에 전달했습니다. 뷰에서는 페이징 링크를 담고 있는 변수 $data['pagination']을 추가해 보도록 하겠습니다.
* bbs/application/views/board/list_v.php
12345678910111213141516171819202122232425262728293031323334353637383940414243<article id="board_area"><header><h1></h1></header><h1></h1><table cellpadding="0" cellspacing="0"><thead><tr><th scope="col">번호</th><th scope="col">제목</th><th scope="col">작성자</th><th scope="col">조회수</th><th scope="col">작성일</th></tr></thead><tbody><?phpforeach($list as $lt){?><tr><th scope="row"><?php echo $lt -> board_id;?></th><td><a rel="external" href="/bbs/<?php echo $this -> uri -> segment(1); ?>/view/<?php echo $this -> uri -> segment(3); ?>/<?php echo $lt -> board_id; ?>"> <?php echo $lt -> subject;?></a></td><td><?php echo $lt -> user_name;?></td><td><?php echo $lt -> hits;?></td><td><time datetime="<?php echo mdate("%Y-%M-%j", human_to_unix($lt -> reg_date)); ?>"><?php echo mdate("%Y-%M-%j", human_to_unix($lt -> reg_date));?></time></td></tr><?php}?></tbody><tfoot><tr><th colspan="5"><?php echo $pagination;?></th></tr></tfoot></table></article>cs Line 39: 뷰 소스에서 <tfoot> 태그를 이용하여 페이징 링크의 HTML 소스를 담고 있는 $pagination 을 화면에 출력하는 것으로 뷰의 작업은 끝입니다.
이번 포스트에서는 페이징 처리까지 진행하고, 다음 포스트에서 검색 만들기 부터 진행하도록 하겠습니다.
* 이 포스트는 서적 '만들면서 배우는 CodeIgniter 프레임워크'를 참고하여 작성하였습니다
'Web > CodeIgniter' 카테고리의 다른 글
[CodeIgniter] 5. 폼 검증하기 (0) 2015.08.24 [CodeIgniter] 4. 게시판 프로젝트 - 수정, 삭제 (0) 2015.08.23 [CodeIgniter] 4. 게시판 프로젝트 - 검색, 입력, 보기 기능 (1) 2015.08.23 [CodeIgniter] 3. Todo 애플리케이션 프로젝트 (0) 2015.08.21 [CodeIgniter] 2. CodeIgniter 개발 환경 구성 (0) 2015.07.17 [CodeIgniter] 1. CodeIgniter 소개 (0) 2015.07.17