🔥

CodeIgniter4入門 公式チュートリアル (2)DBデータの表示

2021/12/06に公開

CodeIgniter Advent Calendar 2021

CodeIgniter4入門 公式チュートリアル (1)静的ページの表示
の続きです。

今回から、データベースを使います。

目次

MySQLでのデータベースの準備

チュートリアル用のデータベースを作成します。

http://localhost:81/ のphpMyAdminにアクセスします。

データベースの作成

データベース ci4tutorial を作成します。

コマンドで作成する場合は、以下を実行します。

CREATE DATABASE `ci4tutorial` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_as_cs;

ユーザ dbuserci4tutorial への権限を付与します。以下のSQL文を実行します。

GRANT ALL PRIVILEGES ON `ci4tutorial`.* TO `dbuser`@`%`;

テーブルの作成

news テーブルを作成します。以下のSQL文を実行します。

CREATE TABLE news (
    id INT UNSIGNED NOT NULL AUTO_INCREMENT,
    title VARCHAR(128) NOT NULL,
    slug VARCHAR(128) NOT NULL,
    body TEXT NOT NULL,
    PRIMARY KEY (id),
    KEY slug (slug)
);

データの挿入

初期データを挿入します。以下のSQL文を実行します。

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.');

挿入したデータを確認します。

CodeIgniter4のデータベース設定

.env ファイルのデータベース接続情報を以下のように設定します。
DB_DATABASEci4tutorial に変更します。

DB_DATABASE = ci4tutorial
DB_USERNAME = dbuser
DB_PASSWORD = dbpassword

database.default.hostname = database
database.default.database = "${DB_DATABASE}"
database.default.username = "${DB_USERNAME}"
database.default.password = "${DB_PASSWORD}"
database.default.DBDriver = MySQLi
database.default.DBPrefix =

NewsModelの作成

news テーブルにアクセスする NewsModel を作成します。

app/Models/NewsModel.php

<?php
namespace App\Models;

use CodeIgniter\Model;

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

    public function getNews($slug = false)
    {
        if ($slug === false) {
            return $this->findAll();
        }
    
        return $this->where(['slug' => $slug])->first();
    }
}

CodeIgniter\ModelfindAll() メソッドと first() メソッドを使い、news テーブルからデータを取得します。

Newsコントローラの作成

News コントローラを作成します。

app/Controllers/News.php

<?php
namespace App\Controllers;

use App\Models\NewsModel;
use CodeIgniter\Controller;
use CodeIgniter\Exceptions\PageNotFoundException;

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

        $data = [
            'news'  => $model->getNews(),
            'title' => 'News archive',
        ];
        dd($data);
    
        echo view('templates/header', $data);
        echo view('news/overview', $data);
        echo view('templates/footer', $data);
    }

    public function view($slug = null)
    {
        $model = model(NewsModel::class);
    
        $data['news'] = $model->getNews($slug);
    
        if (empty($data['news'])) {
            throw new PageNotFoundException('Cannot find the news item: ' . $slug);
        }
    
        $data['title'] = $data['news']['title'];
        dd($data);
    
        echo view('templates/header', $data);
        echo view('news/view', $data);
        echo view('templates/footer', $data);
    }
}

CodeIgniter4の model() 関数は、モデルクラスをインスタンス化します。

CodeIgniter4の dd() 関数で $data の値を表示して確認できるようにしました。

ルーティング設定

前回、全てのルートを Pages コントローラで処理するように、ルーティング設定をしたため、現状だと News コントローラにアクセスできません。

そこで、News コントローラにアクセスするためのルートを追加します。

app/Config/Routes.php

--- a/app/Config/Routes.php
+++ b/app/Config/Routes.php
@@ -33,6 +33,8 @@ $routes->setAutoRoute(true);
 // route since we don't have to scan directories.
 $routes->get('/', 'Home::index');
 
+$routes->get('news/(:segment)', 'News::view/$1');
+$routes->get('news', 'News::index');
 $routes->get('(:any)', 'Pages::view/$1');
 
 /*

http://localhost/news にアクセスすると、CodeIgniter4の dd() メソッドで $data の値が表示されます。

データベースに登録したレコードの値が取得できていることがわかります。

http://localhost/news/elvis-sighted にもアクセスしてみましょう。

データベースとのやりとりを確認できたら、デバッグ用の dd() 関数を削除しておきます。

--- a/app/Controllers/News.php
+++ b/app/Controllers/News.php
@@ -15,7 +15,6 @@ class News extends Controller
             'news'  => $model->getNews(),
             'title' => 'News archive',
         ];
-        dd($data);
 
         echo view('templates/header', $data);
         echo view('news/overview', $data);
@@ -33,7 +32,6 @@ class News extends Controller
         }
 
         $data['title'] = $data['news']['title'];
-        dd($data);
 
         echo view('templates/header', $data);
         echo view('news/view', $data);

Viewファイルの作成

一覧ページ用の app/Views/news/overview.php を追加します。

<h2><?= esc($title) ?></h2>

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

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

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

        <div class="main">
            <?= esc($news_item['body']) ?>
        </div>
        <p><a href="/news/<?= esc($news_item['slug'], 'url') ?>">View article</a></p>

    <?php endforeach ?>

<?php else: ?>

    <h3>No News</h3>

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

<?php endif ?>

CodeIgniter4の esc() 関数は、HTMLでのエスケープ処理をする関数です。
XSS脆弱性を作り込まないように、原則としてビューでは全ての変数をこの関数で処理します。

また、<a> タグの href 属性の値を出力する際には、第2引数にコンテキスト url を指定し、
esc($news_item['slug'], 'url') のように使います。

続いて、個別記事ページ用の app/Views/news/view.php を追加します。

<h2><?= esc($news['title']); ?></h2>
<p><?= esc($news['body']); ?></p>

これで、ビューファイルが全て用意できました。

表示の確認

http://localhost/news にアクセスしてみます。

記事の一覧が表示されました。

「View article」をクリックして、http://localhost/news/elvis-sighted にアクセスします。

個別の記事も表示されています。

CodeIgniter4入門 公式チュートリアル (3)DBへのデータの追加
へ続く。

参考

Discussion