뉴스 섹션

이전 섹션에서는 정적 페이지(static page)를 참조하는 클래스를 작성하여 프레임워크의 몇 가지 기본 개념을 살펴 보고 사용자 정의 라우팅 규칙을 추가하여 URI를 정리했습니다. 이제 동적(dinamic) 컨텐츠를 소개하고 데이터베이스를 사용할 차례입니다.

작업 할 데이터베이스 생성

먼저, CodeIgniter 설치시 요구사항에 요약 된대로 적절한 데이터베이스를 설정했다고 가정합니다. 이 튜토리얼에서는 MySQL 데이터베이스에 대한 SQL을 제공하며, 데이터베이스 명령을 실행하기에 적합한 클라이언트(mysql, MySQL Workbench 또는 phpMyAdmin)가 있다고 가정합니다.

이 섹션을 진행하기 위해서는 데이터베이스를 만든 다음 CodeIgniter를 구성하여 사용해야 합니다.

데이터베이스 클라이언트를 사용하여 데이터베이스에 연결하고 아래의 SQL(MySQL)을 실행하십시오. 또한, 몇 개의 시드(seed) 레코드를 추가합니다. 지금은 테이블을 만드는데 필요한 SQL문을 보여 주지만 CodeIgniter에 익숙해지면 프로그래밍 방식으로이 작업을 수행할 수 있습니다. 나중에 더 유용한 데이터베이스 설정을 작성하기 위해 마이그레이션시드(Seeds)에 대해 읽어보세요.

CREATE TABLE news (
        id int(11) NOT NULL AUTO_INCREMENT,
        title varchar(128) NOT NULL,
        slug varchar(128) NOT NULL,
        body text NOT NULL,
        PRIMARY KEY (id),
        KEY slug (slug)
);

관심사항: 웹과 관련하여 슬러그(slug)는 URL을 사용하여 리소스를 식별하고 설명하는데 사용되는 SEO 친화적인 짧은 텍스트입니다.

시드(seed) 레코드는 다음과 같습니다.:

INSERT INTO news VALUES
(1,'Elvis sighted','elvis-sighted','Elvis was sighted at the Podunk internet cafe. It looked like he was writing a CodeIgniter app.'),
(2,'Say it isn\'t so!','say-it-isnt-so','Scientists conclude that some programmers have a sense of humor.'),
(3,'Caffeination, Yes!','caffeination-yes','World\'s largest coffee shop open onsite nested coffee shop for staff only.');

데이터베이스에 연결

CodeIgniter를 설치할 때 생성한 로컬 구성 파일 .env를 열어 데이터베이스 속성의 주석을 해제하고 사용하려는 데이터베이스에 맞게 설정하십시오.:

database.default.hostname = localhost
database.default.database = ci4tutorial
database.default.username = root
database.default.password = root
database.default.DBDriver = MySQLi

모델(model) 설정

컨트롤러에서 데이터베이스 작업을 바로 작성하는 대신 쿼리를 모델에 배치하면 나중에 쉽게 재사용 할 수 있습니다. 모델은 데이터베이스 또는 다른 데이터 저장소에서 정보를 검색, 삽입 및 업데이트하는 장소입니다. 그들은 데이터에 대한 액세스를 제공합니다.

app/Models/ 디렉터리에 NewsModel.php라는 새 파일을 만들고 다음 코드를 추가하십시오. 여기에 설명 된대로 데이터베이스를 올바르게 구성했는지 확인하십시오.

<?php namespace App\Models;
use CodeIgniter\Model;

class NewsModel extends Model
{
        protected $table = 'news';
}

이 코드는 앞서 사용한 컨트롤러 코드와 비슷합니다. CodeIgniter\Model을 확장하여 새 모델을 만들고 데이터베이스 라이브러리를 로드합니다. 이렇게 하면 $this->db 객체를 통해 데이터베이스 클래스를 사용할 수 있게 됩니다.

데이터베이스와 모델이 설정되었으므로 데이터베이스에서 모든 게시물을 가져올 방법이 필요합니다. 이를 위해 CodeIgniter에 포함 된 데이터베이스 추상화 계층인 Query Builder를 사용합니다. 이를 통해 한 번 작성된 쿼리는 지원되는 모든 데이터베이스 시스템에서 작동할 수 있습니다. Model 클래스를 사용하면 Query Builder로 쉽게 작업 할 수 있으며 데이터 작업을 보다 간단하게 수행할 수 있는 추가 도구도 제공됩니다. 다음 코드를 모델에 추가하십시오.

public function getNews($slug = false)
{
        if ($slug === false)
        {
                return $this->findAll();
        }

        return $this->asArray()
                     ->where(['slug' => $slug])
                     ->first();
}

이 코드를 사용하면 두 가지 다른 쿼리를 수행 할 수 있습니다. 모든 뉴스 레코드를 얻거나, slug를 통해 뉴스 항목을 얻을 수 있습니다. Query Builder를 실행하기 전 $slug 변수에 값이 제거되지 않았습니다.

여기서 사용되는 두 가지 메서드 findAll()first()는 모델 클래스에 의해 제공됩니다. 이 두 메서드는 이미 우리가 앞서 NewsModel 클래스에 설정한 $table 속성을 기준으로 사용할 테이블를 알고 있습니다. 이 메서드는 Query Builder를 사용하여 현재 테이블에서 명령을 실행하고 원하는 형식으로 결과 배열을 반환하는 도우미(helper) 메서드입니다. 이 예에서 findAll()은 일련의 객체(object)를 반환합니다.

뉴스 표시

쿼리가 작성되었으므로 모델은 뉴스 항목을 사용자에게 표시할 뷰와 연결되어야 합니다. 이는 앞서 만든 Pages 컨트롤러에서 할 수 있지만, 명확한 연결을 위해 새로운 News 컨트롤러를 정의합니다. app/Controllers/News.php로 새 컨트롤러를 생성하십시오.

<?php namespace App\Controllers;
use App\Models\NewsModel;
use CodeIgniter\Controller;

class News extends Controller
{
        public function index()
        {
                $model = new NewsModel();

                $data['news'] = $model->getNews();
        }

        public function view($slug = null)
        {
                $model = new NewsModel();

                $data['news'] = $model->getNews($slug);
        }
}

코드를 살펴보면 앞서 만든 파일과 비슷한 점이 있을 수 있습니다. 첫째, 핵심 CodeIgniter 클래스인 Controller를 확장하여 몇 가지 도우미 메서드를 제공하며, 디스크에 정보를 저장하는 Logger 클래스와 RequestResponse 객체를 사용할 수 있도록 합니다. 다음으로 두 가지 메서드가 있는데, 모든 뉴스 항목을 보는 메서드와 특정 뉴스 항목을 보는 메서드입니다. 두 번째 메서드에서는 $slug 변수가 모델의 메서드로 전달되는 것을 볼 수 있습니다. 모델은 이 slug를 사용하여 뉴스 항목을 식별합니다.

이제 데이터는 모델을 통해 컨트롤러에 검색되지만, 아직 아무것도 표시되지 않습니다. 다음으로 해야할 일은 이 데이터를 뷰에 전달하는 것입니다. index() 메서드를 다음과 같이 수정하십시오.:

public function index()
{
        $model = new NewsModel();

        $data = [
                'news'  => $model->getNews(),
                'title' => 'News archive',
        ];

        echo view('templates/header', $data);
        echo view('news/overview', $data);
        echo view('templates/footer');
}

위의 코드는 모델로부터 모든 뉴스를 가져와 변수에 할당합니다. title의 값은 $data['title'] 요소에 할당되며 모든 데이터는 뷰로 전달됩니다. 뉴스 항목을 렌더링하려면 뷰를 작성해야합니다. app/Views/news/overview.php를 생성하고 다음 코드를 추가합니다.

<h2><?= $title ?></h2>

<?php if (! empty($news) && is_array($news)) : ?>

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

                <h3><?= $news_item['title'] ?></h3>

                <div class="main">
                        <?= $news_item['body'] ?>
                </div>
                <p><a href="<?= '/news/'.$news_item['slug'] ?>">View article</a></p>

        <?php endforeach; ?>

<?php else : ?>

        <h3>No News</h3>

        <p>Unable to find any news for you.</p>

<?php endif ?>

여기서, 각 뉴스 항목은 루프를 이용하여 사용자에게 표시됩니다. 우리는 템플릿에 HTML과 PHP를 섞어 사용한 것을 볼 수 있습니다. 템플릿 언어를 사용하고 싶다면 CodeIgniter의 View Parser 또는 타사의 파서를 사용하십시오.

뉴스 개요(overview) 페이지는 현재 완료되었지만, 개별 뉴스 항목을 표시할 페이지는 여전히 없습니다. 앞서 만든 모델은 이 기능을 쉽게 사용할 수 있도록 만들어졌습니다. 컨트롤러에 일부 코드를 추가하고 새로운 뷰를 작성하면 됩니다. News 컨트롤러로 돌아가서 다음과 같이 view() 메서드를 업데이트하십시오.

public function view($slug = NULL)
{
        $model = new NewsModel();

        $data['news'] = $model->getNews($slug);

        if (empty($data['news']))
        {
                throw new \CodeIgniter\Exceptions\PageNotFoundException('Cannot find the news item: '. $slug);
        }

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

        echo view('templates/header', $data);
        echo view('news/view', $data);
        echo view('templates/footer');
}

매개 변수없이 getNews() 메서드를 호출하는 대신 $slug 변수가 전달되므로 특정 뉴스 항목을 반환합니다. 이제 남은 것은 뷰를 만드는 일입니다. app/Views/news/view.php 파일에 다음 코드를 추가하세요.

<?php
echo '<h2>'.$news['title'].'</h2>';
echo $news['body'];

라우팅

앞서 만든 와일드카드(:any) 라우팅 규칙 때문에 방금 만든 컨트롤러를 보려면 새로운 라우팅 규칙이 필요합니다. 다음과 같이 라우팅 파일(app/config/routes.php)을 수정하십시오. 이를 통해 요청이 Pages 컨트롤러로 직접 이동하지 않고 News 컨트롤러에 도달할 수 있습니다.

$routes->get('news/(:segment)', 'News::view/$1');
$routes->get('news', 'News::index');
$routes->get('(:any)', 'Pages::showme/$1');

브라우저를 “news” 페이지(예: localhost:8080/news)로 지정하면 뉴스 항목 목록이 표시되며, 각 항목에는 기사 하나만 표시할 수 있는 링크가 제공됩니다.

../_images/tutorial2.png