원문: http://ellislab.com/codeigniter/user-guide/tutorial/news_section.html



지난 튜토리얼에서는 프레임워크의 기본 개념을 익히기 위해서 정적인 페이지를 포함하는 클래스를 작성해 봤다. 또한 URI을 더 깔끔하게 만들기 위해서, 커스텀 라우팅 규칙을 추가했다. 이제 동적인 컨텐츠를 추가하는 방법과, 데이터베이스를 사용하는 방법을 설명할 차례다.



모델 설정하기


데이터베이스를 활용하는 코드를 컨트롤러에 직접 작성하기보다는, 쿼리는 반드시 모델에 위치시켜야만 하는데, 이렇게 분리를 해야만 나중에 재사용하기가 쉽기 때문이다. 모델은 데이터베이스 또는 데이터 저장소로부터 정보를 가져오거나, 추가하고, 수정하기 위한 코드들이 위치하는 곳이다. 여러분이 가진 데이터에 해당하는 부분이 바로 모델이다.


application/models 디렉토리를 열어서, news_model.php 파일을 생성한 후, 아래의 코드를 추가한다.

<?php

class News_model extends CI_Model {

    public function __construct() {

        $this -> load -> database();

    }

}

?>


앞서 만들었던 컨트롤러 코드와 매우 유사하다. 모델은 CI_Model 클래스를 상속받아서 생성한 후, 데이터베이스 라이브러리를 로드하게 된다. 이제 $this->db 객체를 사용하여 데이터베이스 클래스를 사용할 수 있게 된다. 


데이터베이스 쿼리를 실행하기 전에, 먼저 데이터베이스 스키마를 만들어야 한다. 데이터베이스 접속한후, 아래의 SQL 명령어를 실행한다. 그리고 몇가지 샘플 레코드를 추가하자.

CREATE TABLE news (

id int(11) NOT NULL AUTO_INCREMENT,

title varchar(128) NOT NULL,

slug varchar(128) NOT NULL,

text text NOT NULL,

PRIMARY KEY (id),

KEY slug (slug)

);


역주) 아래의 입력문을 사용해서 샘플 데이터를 입력해두자

INSERT INTO news VALUES (1, 'hot item -1', 'pants-1', 'item is selled -1');

INSERT INTO news VALUES (2, 'hot item -2', 'pants-2', 'item is selled -2');

INSERT INTO news VALUES (3, 'hot item -3', 'pants-3', 'item is selled -3');


데이터베이스와 모델에 대한 준비가 되었으므로, 이제 데이터베이스로부터 모든 뉴스를 가져올 수 있는 메서드를 만들어보자. 이를 위해서는 데이터베이스 추상화 레이어가 필요하다. CodeIgniter에서는 Actie Record를 사용한다. 이처럼 추상화 레이어를 사용하ㅔ 되면, 하나의 쿼리만을 사용해서 다양한 데이터베이스 시스템에서 동작하도록 할 수 있게 된다. 아래의 코드를 모델에 추가하자.

public function get_news($slug = FALSE) {

    if ($slug === FALSE) {

        $query = $this -> db -> get('news');

        return $query -> result_array();

    }


    $query = $this -> db -> get_where('news', array('slug' => $slug));

    return $query -> row_array();

}


이 코드를 사용하면 2가지 서로 다른 쿼리를 실행할 수 있다. 모든 뉴스 레코드를 가져오거나, 또는 slug에 해당하는 뉴스 아이템만을 가져올 수도 있다. $slug 변수에 대한 유효성 검증을 하지 않은 채로 쿼리를 실행했다다는 사실을 알 수 있다. Active Record가 검증을 처리하니 신경쓰지 않아도 된다.



뉴스 표시하기


퀴리를 작성하였으니, 이제 모델과 뷰를 연결하여 뉴스 아이템을 사용장에게 표시해야 한다. 이 작업은 앞에서 만든 pages 컨트롤러를 사용하여 처리할 수 있다. 하지만 명료성을 위해서, 새로운 "news"  컨트롤러를 정의하자. application/controllers/news.php 파일을 아래와 같이 생성하자.

<?php

class News extends CI_Controller {

    public function __construct() {

        parent::__construct();

        $this -> load -> model('news_model');

    }


    public function index() {

        $data['news'] = $this -> news_model -> get_news();

    }


    public function view($slug) {

        $data['news'] = $this -> news_model -> get_news($slug);

    }

}

?>


코드를 보면, 앞에서 만든 모델 클래스와 유사하다는 점을 알 수 있다. 먼저, "__construct" 메서드다. 이 메서드에서는 부모 클래스(CI_Controller)의 생성자(__construct)를 호출한 후, 모델을 로드한다. 따라서 컨트롤러 안에서 부모 클래스와 모델 클래스의 메서드를 사용할 수 있게 된다.


두번째, 모든 뉴스 아이템을 보기 위한 메서드(index)와 특정 뉴스 하나를 보기 위한 메서드(view)가 있다. $slug 변수가 두 번째 메서드(view)에서 모델의 메서드에 전달된다는 사실을 볼 수 있다. 모델에서는 $slug 변수를 사용하여 반환할 뉴스 아이템을 식별해 낸다. 


이제 컨트롤러는 모델을 통해서 데이터를 모두가져왔지만, 아직 어느 데이터도 표시하지는 않았다. 다음으로 할일이 바로 데이터를 뷰로 전달하는 일이다.

public function index() {

    $data['news'] = $this -> news_model -> get_news();

    $data['title'] = 'News archive';


    $this -> load -> view('templates/header', $data);

    $this -> load -> view('news/index', $data);

    $this -> load -> view('templates/footer');

}


위의 코드에서는 모델로부터 모든 뉴스 레코드를 가져와서, 변수에 할당한다. 타이틀에 해당하는 값 또한 $data['title'] 요소에 할당한 후, 모든 데이터를 뷰로 전달한다. 이제는 뷰를 생성하여, 뉴스 아이템을 렌더링 해보자. application/views/news/index.php 파일을 만들어서 아래의 코드를 추가하자.

<?php foreach ($news as $news_item): ?>


    <h2><?php echo $news_item['title'] ?></h2>

    <div id="main">

        <?php echo $news_item['text'] ?>

    </div>

    <p><a href="news/<?php echo $news_item['slug'] ?>">View article</a></p>


<?php endforeach ?>


여기에서는 각 뉴스 아이템에 대해 루프를 돌면서 사용자에게 표시한다. 보다시피 여기에서는 템플릿 파일에 PHP와 HTML을 섞어서 작성했다. 만약 템플릿 엔진을 사용하고 싶다면, CodeIgniter에서 제공하는 Template Parser 클래스를 사용하거나, 또는 써드파티 파서를 사용할 수 있다.


뉴스에 대한 개략적인 정보를 보는 페이지는 다 만들었다. 이제 각 뉴스 아이템을 표시하는 페이지를 만들어보자. 앞서 만든 모델은 이 기능을 효과적으로 처리할 수 있는 형식으로 개발했다. 따라서 그저 컨트롤러에 약간의 코드를 추가하고, 새로운 뷰를 하나 만들면 충분하다. news 컨트롤러로 다시 가서, 아래와 코드를 추가하자.

public function view($slug) {

    $data['news_item'] = $this -> news_model -> get_news($slug);


    if (empty($data['news_item'])) {

        show_404();

    }


    $data['title'] = $data['news_item']['title'];


    $this -> load -> view('templates/header', $data);

    $this -> load -> view('news/view', $data);

    $this -> load -> view('templates/footer');

}


get_news() 메서드를 파라미터 없이 호출하는게 아니라, $slug 변수를 전달한다. 그래야만 특정 뉴스 아이템만을 반환하게 된다. 이제 남은 일은 대응하는 뷰를 application/views/news/view.php 파일을 만드는 일 뿐이다. 아래의 코드를 이 파일에 추가하자.

<?php

echo '<h2>'.$news_item['title'].'</h2>';

echo $news_item['text'];

?>



라우팅


앞에서 와일드카드를 이용하여 라우팅 규칙을 설정했기 때문에, 지금 만든 컨트롤러를 보기 위해서는 몇가지 라우팅을 추가할 필요가 있다. 라우팅 파일(application/config/routes.php) 파일을 아래와 같이 수정하자. 이렇게 해야만 요청이 pages 컨트롤러로 바로 전달되지 않고, news 컨트롤러로 전달되도록 할 수 있다. 첫 번째 라인에서는 slug를 가지는 URI는 news 컨트롤러의 view 메서드로 전달되도록 라우팅한다.

$route['news/(:any)'] = 'news/view/$1';

$route['news'] = 'news';

$route['default_controller'] = 'pages/view';

$route['(:any)'] = 'pages/view/$1';



  

Posted by socurites