ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    <?php
    if (!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


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    <?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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    <?php
    if (!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

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    <!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


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    <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>
                <?php
    foreach($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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    <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


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
     
    <?php
    if (!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(51);
     
            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


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
    <?php
    if (!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


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
     
     
    <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>
                <?php
    foreach($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 프레임워크'를 참고하여 작성하였습니다

    댓글

Designed by Tistory.