今回はCodeIgniter4でブログを作るチュートリアルを行います。
0.事前準備
実装を始める事前準備として以下の記事を読んでいただけると幸いです。
1.ホーム画面を作る
まずはホーム画面の作成です。
1-1.ルーティングの設定
それではまず、ルーティングを編集していきます。
$routes->get('/', 'Pages::index');
$routes->get('(:any)', 'Pages::showme/$1');
ホーム画面としてPagesクラスのindexメソッドとその他のページ(今回のプロジェクトではaboutページ)のためのshowmeメソッドを用意します。(:any)の部分がメソッドの引数となります。
1-2.コントローラーの作成
次にPagesクラスをApp/Controllers/に作成して編集していきます。
<?php
namespace App\Controllers;
use App\Models\BlogModel;
class Pages extends BaseController
{
public function index()
{
$model = new BlogModel();
$data['news'] = $model->getPosts();
echo view('templates/header', $data);
echo view('pages/home');
echo view('templates/footer');
}
public function showme($page = 'home')
{
if(!is_file(APPPATH.'/Views/pages/'.$page.'.php'))
{
throw new \CodeIgniter\Exceptions\PageNotFoundException($page);
}
$model = new BlogModel();
$data['news'] = $model->getPosts();
echo view('templates/header');
echo view('pages/'.$page);
echo view('templates/footer');
}
}
BlogModelを用いるので3行目でBlogModelの使用を宣言しておきます。
index()においては、ブログの全記事を取得し、取得した記事をViewで表示するメソッドになっています。
showme()では、 引数と同じ名前のViewファイルを表示し、もし引数と同名のViewファイルが存在しなければ、エラーメッセージを表示します。
showmeメソッドはデフォルトでhomeが引数に設定されており、引数が渡されない場合はホーム画面へ遷移するようになっています。
1-3.モデルの作成
次にModelを作成します。
App/Models/にBlogModel.phpを作成して編集します。
<?php
namespace App\Models;
use CodeIgniter\Model;
class BlogModel extends Model
{
protected $table = 'posts';
public function getPosts($slug = null)
{
if(!$slug)
{
return $this->findAll();
}
return $this->asArray()
->where(['slug' => $slug])
->first();
}
}
まず、このクラスで使用するテーブルを設定します。
次に、記事を取得するgetPostをメソッドを作成します。
引数にはデフォルトでnullを宣言しておき、もし引数があれば引数を元に特定の記事のデータを、引数がなければ全てのデータを取得するメソッドを定義しておきます。
これでホーム画面で記事一覧を取得することができます。
1-4.ビューの作成
最後にViewを作成していきます。
App/Views/にpages.phpを作成し、編集します。
<section class="blog-section">
<div>
<?php if($news): ?>
<?php foreach($news as $newsItem): ?>
<h3><a href="/blog/<?=$newsItem['slug'] ?>"><?=$newsItem['title'] ?></a></h3>
<?php endforeach; ?>
<?php else: ?>
<p class="text-center">No posts have been found</p>
<?php endif; ?>
</div>
</section>
ここでは、$data[‘news’]にデータが代入されていた場合、記事一覧として表示します。
2.記事閲覧ページを作る
続いて、記事の詳細を見ることができる詳細ページを作っていきます。
2-1.ルーティングの編集
まずはルーティングを追加していきましょう。
$routes->get('/blog/(:any)', 'Blog::post/$1');
(:any)部分が引数となって、Blogコントローラーのpostメソッドを呼び出します。
2-2.コントローラーの編集
それでは新しくBlogコントローラーをApp/Controllersに作成し編集していきます。
<?php
namespace App\Controllers;
use App\Models\BlogModel;
class Blog extends BaseController
{
publicfunction post($page)
{
$model = new BlogModel();
$data['post'] = $model->getPosts($page);
echo view('templates/header', $data);
echo view('blog/post');
echo view('templates/footer');
}
}
postメソッドでは前回作成したBlogModelのgetPostを用います。
今回は特定のデータを取得したいので、テーブルの’slug’と一致する引数$pageをgetPostに渡し、Modelのメソッドを実行します。
取得したデータは$data[‘post’]に代入され、Viewにおいて$postとして扱うことができます。
2-3.モデルの編集
モデルは前回作成したBlogModelを使用します。
<?php
namespace App\Models;
use CodeIgniter\Model;
class BlogModel extends Model
{
protected $table = 'posts';
publicfunction getPosts($slug = null)
{
if(!$slug)
{
return $this->findAll();
}
return $this->asArray()
->where(['slug' => $slug])
->first();
}
}
前回は引数なしでgetPostメソッドを呼び出したため、条件分岐によりテーブルにあるすべての項目を取得しましたが、今回は引数があるため、’slug’カラムが 引数と一致するデータを取得します。
2-4.ビューの編集
最後にApp\View\にPost.phpを作成します。
<section>
<div class="container">
<article class="blog-post">
<h1><?= $post['title']?></h1>
<div class="details">
Posted on : <?= date('M d Y', strtotime($post['posted_at']));?> by <a href="">Shintaro</a>
</div>
<?= $post['body'] ?>
</article>
</div>
</section>
このページでは、取得したデータそれぞれを表示する画面となっています。
3.記事投稿機能を実装する
続いて記事投稿機能を実装していきます。
3-1.ルーティングの追加
まずは、ルーティングの追加から行いましょう。
$routes->get('/blog/create', 'Blog::create');
/blog/createにアクセスするとBlogコントローラーののcreateメソッドを呼び出します。
3-2.コントローラーの編集
次に前回作成したApp\ControllersのBlog.phpにcreateメソッドを追加します。
function create()
{
helper('form');
$model = new BlogModel();
if(! $this->validate([
'title' => 'required|min_length[3]|max_length[255]',
'body' => 'required'
])){
echo view('templates/header');
echo view('blog/create');
echo view('templates/footer');
}
else{
$model->save([
'title' => $this->request->getVar('title'),
'body' => $this->request->getVar('body'),
'slug' => url_title($this->request->getVar('title'))
]);
$session = \Config\Services::session();
$session->setFlashData('success' , 'New post was created!');
return redirect()->to('/');
}
}
最初にformのhelperメソッドを呼び出しています。このメソッドを用いるとバリデーションなど多くのformに関する便利なメソッドが使用可能になります。
より詳細は下記ページの公式ドキュメントをご参照ください。
その下では、Modelを宣言した後、バリデーションをクリアできなければ、Viewのcreateが呼び出され、そうでなければデータベースにデータを保存するという条件分岐となっています。
もし、投稿が成功すれば、セッションのsuccessの中に投稿成功の文言を格納し、ホーム画面へと遷移します。
今回はModelの特別書き加えた部分はなかったのでModelの説明は省きます。
3-3.ビューの作成
次にViewの作成です。
まずは、投稿フォームのあるビューであるcreate.phpをApp\Viewsに作成します。
<div class="container">
<h1>Cerate new post</h1>
<?php if($_POST):?>
<?=\Config\Services::validation()->listErrors(); ?>
<?php endif; ?>
<form action="/blog/create" method="post">
<div class="form-group">
<label for="title">Title;</label>
<input type="text" class="form-control" name="title" id="change" value="">
</div>
<div class="form-group">
<label for="body">Body</label>
<textarea class="form-control" name="body" id="body"></textarea>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Create</button>
</div>
</form>
</div>
まず、もし$_POSTに何か格納されてこのページに遷移している場合は、バリデーションエラーが起きているので、<?=\Config\Services::validation()->listErrors(); ?>でバリデーションエラーのメッセージを表示します。これもhelper(‘form’)をコントローラーで呼び出しているため使えるメソッドでバリデーションの内容によって勝手にエラ〜メッセージを作成してくれます。
それ以外は通常のフォームを作成し、上で作ったルーティングと同じ/blog/createにPOSTするようにします。これで記事の投稿機能の実装は完了しました。
今回はhelper(‘form’)を用いているため、form_open()を用いるとcsrf対策が可能です。
最後に投稿に成功した後にホーム画面に遷移した際に先ほどセッションの中に格納した投稿成功の文言を表示します。
home.phpの最初の部分に以下の記述を足します。
<?php $session = \Config\Services::session(); ?>
<?php if(isset($session->success)): ?>
<div>
<?= $session->success ?>
</div>
<?php endif ?>
これでBlogアプリは完成です。
参考記事の紹介
今回はここまでになります。最後まで閲覧くださりありがとうございました。