CodeIgniter4の公式チュートリアルをやってみる (3)
(2021-12-05 追記) この記事は古くなっています。 「CodeIgniter4入門 公式チュートリアル (1)静的ページの表示」 を参照してください。
この記事は CodeIgniter Advent Calendar 2020 - Qiita の4日目です。まだ、空きがありますので、興味のある方は気軽に参加してください。
CodeIgniter 4 の公式ドキュメントにあるチュートリアルを続けます。
CodeIgniter4の公式チュートリアルをやってみる (2) の続きです。
データベースへの書き込みを実装します。
Form の作成
記事を書き込むためのビューファイル app/Views/news/create.php
を作成します。
<h2><?= esc($title); ?></h2>
<?= \Config\Services::validation()->listErrors(); ?>
<form action="/news/create" method="post">
<?= csrf_field() ?>
<label for="title">Title</label>
<input type="input" name="title" /><br />
<label for="body">Text</label>
<textarea name="body"></textarea><br />
<input type="submit" name="submit" value="Create news item" />
</form>
\Config\Services
クラスは CodeIgniter4 のサービスロケータです。
CodeIgniter4 では、フレームワークのクラスはサービスとして、サービスロケータから取得できます。
\Config\Services::validation()
メソッドは、CodeIgniter4 の Validation クラスを返します。
Form を受け取るためのコントローラメソッドの追加
News コントローラに Form を受け取るための create()
メソッドを追加します。
--- a/app/Controllers/News.php
+++ b/app/Controllers/News.php
@@ -40,4 +40,30 @@ class News extends Controller
echo view('news/view', $data);
echo view('templates/footer', $data);
}
+
+ public function create()
+ {
+ $model = new NewsModel();
+
+ if ($this->request->getMethod() === 'post' && $this->validate([
+ 'title' => 'required|min_length[3]|max_length[255]',
+ 'body' => 'required',
+ ]))
+ {
+ $model->save([
+ 'title' => $this->request->getPost('title'),
+ 'slug' => url_title($this->request->getPost('title'), '-', TRUE),
+ 'body' => $this->request->getPost('body'),
+ ]);
+
+ echo view('news/success');
+
+ }
+ else
+ {
+ echo view('templates/header', ['title' => 'Create a news item']);
+ echo view('news/create');
+ echo view('templates/footer');
+ }
+ }
}
コントローラの $this->validate()
メソッドは、リクエストのデータを検証するための便利なメソッドです。
Model クラスの save()
メソッドは、データを挿入または更新するメソッドです。今回は、プライマリキーの指定がないため全て挿入処理になります。
書き込み成功時のビューの追加
書き込みが成功した旨のメッセージを表示するための app/Views/news/success.php
を追加します。
News item created successfully.
NewsModel の変更
NewsModel がデータを保存できるように、$allowedFields
プロパティに変更可能なカラムを設定します。
--- a/app/Models/NewsModel.php
+++ b/app/Models/NewsModel.php
@@ -7,6 +7,8 @@ class NewsModel extends Model
{
protected $table = 'news';
+ protected $allowedFields = ['title', 'slug', 'body'];
+
public function getNews($slug = false)
{
if ($slug === false)
ルーティングの追加
News コントローラの create() メソッドへのルーティングを追加します。
--- a/app/Config/Routes.php
+++ b/app/Config/Routes.php
@@ -32,6 +32,7 @@ $routes->setAutoRoute(true);
// route since we don't have to scan directories.
$routes->get('/', 'Home::index');
+$routes->match(['get', 'post'], 'news/create', 'News::create');
$routes->get('news/(:segment)', 'News::view/$1');
$routes->get('news', 'News::index');
$routes->get('(:any)', 'Pages::view/$1');
news/create
に GET または POST でアクセスされた場合に、News::create()
メソッドを呼び出します。
記事の追加
では、http://localhost:8080/news/create にアクセスしてみましょう。
記事を入力して、「Create news item」ボタンを押します。
書き込みに成功しました。
プロファイラでデータベースクエリを確認してみます。
一覧を表示してみます。
一番下に追加した記事が表示されています。
以上で公式チュートリアルの内容は完了しました。データベースからの読み込みと書き込み処理までが含まれています。
News コントローラと NewsModel
コントローラとモデルのコードは以下のようになっています。
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 = new NewsModel();
$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 = new NewsModel();
$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);
}
public function create()
{
$model = new NewsModel();
if ($this->request->getMethod() === 'post' && $this->validate([
'title' => 'required|min_length[3]|max_length[255]',
'body' => 'required',
]))
{
$model->save([
'title' => $this->request->getPost('title'),
'slug' => url_title($this->request->getPost('title'), '-', TRUE),
'body' => $this->request->getPost('body'),
]);
echo view('news/success');
}
else
{
echo view('templates/header', ['title' => 'Create a news item']);
echo view('news/create');
echo view('templates/footer');
}
}
}
app/Models/NewsModel.php
<?php
namespace App\Models;
use CodeIgniter\Model;
class NewsModel extends Model
{
protected $table = 'news';
protected $allowedFields = ['title', 'slug', 'body'];
public function getNews($slug = false)
{
if ($slug === false)
{
return $this->findAll();
}
return $this->asArray()
->where(['slug' => $slug])
->first();
}
}
CodeIgniter3 と比べて、変わった?あまり変わらない?どうでしょうか?
このチュートリアルは CodeIgniter3 のチュートリアルとほぼ同一なのですが、実は XSS 対策が追加されています。
この記事は CodeIgniter Advent Calendar 2020 - Qiita の4日目です。まだ、空きがありますので、興味のある方は気軽に参加してください。
参考
Date: 2020/12/04