CodeIgniter4で新しいCI_ENVIRONMENTを定義する

CI_ENVIRONMENT

CodeIgniter4ではデフォルトで、production, development, testing の3つ環境が定義されています。

  • production ... デフォルト。本番環境用
  • development ... 開発環境用
  • testing ... PHPUnitのテスト環境用

何も設定しないと production となり、エラーが起こっても「Whoops!」としか表示されません。

設定変更は、.env ファイルか環境変数を設定することで可能です。通常、開発時には、development を指定します。

.env

CI_ENVIRONMENT = development

testing はPHPUnitの実行時に使われる特殊な環境です。CodeIgniter内部の振る舞いがPHPUnit用に変わりますので、開発やテスト環境で指定することはできません。

例えば、ステージングで production というのは紛らわしいのでいやだ、など定義済みの環境では合わない要求がある場合、新しい環境を定義します。

新しい環境の作成方法

新しい環境を追加するのに必要なことは、Bootファイルを作成するだけです。

例えば、staging 環境を作成したい場合は、app/Config/Boot/staging.php を作成します。

すでに、app/Config/Boot/development.phpapp/Config/Boot/production.php がありますので、それらをコピーして作成してください。

なお、app/Config/Boot/staging.php がない状態で、CI_ENVIRONMENTstaging を設定すると、以下のエラーメッセージが表示されます。

The application environment is not set correctly.

参考

Tags: codeigniter, codeigniter4

CodeIgniter4のアプリケーションフローチャート

Application Flow Chart

CodeIgniter3のユーザガイドには、Application Flow Chartという図がありました。

しかし、CodeIgniter4のユーザガイドにはありません。

そこで作図してみました。

Securityがなくなっていますが、もともとCodeIgniter3でも入力時のフィルタリングだけでセキュリティが確保できるわけではなく、当初あったグローバル変数のサニタイズ処理もかなり以前に削除されていました(グローバル変数のサニタイズ処理が廃止されるのはCodeIgniter 3.2からでした)。ですから、CodeIgniter3のフローチャートにSecurityが残っているのはもともとの名残りみたいなものです。

基本的にCodeIgniter4のアプリケーションフローは、CodeIgniter3と比較して、コントローラの前後にフィルターが追加されただけです。 細かい実装は別にして、大きな流れはほぼ変わりません。

Page CachingもCodeIgniter3と変わらず、デフォルトはオフです。キャッシュしたい場合は、コントローラ単位で指定します。

参考

Tags: codeigniter, codeigniter4

CodeIgniter4のEntityを使う場合

CodeIgniter\Model

CodeIgniter4のチュートリアルのモデルでは、以下のようにEntityは使っていませんでした。

これをEntityを使うように変更してみましょう。

<?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->where(['slug' => $slug])->first();
    }
}

News Entityの作成

CodeIgniter\Entity\Entity を継承したEntityクラスを作成します。

app/Entitles/News.php

<?php

namespace App\Entities;

use CodeIgniter\Entity\Entity;

class News extends Entity
{
}

NewsModelの変更

$returnType プロパティにEntityクラス名を指定します。

--- a/app/Models/NewsModel.php
+++ b/app/Models/NewsModel.php
@@ -2,6 +2,7 @@

 namespace App\Models;

+use App\Entities\News;
 use CodeIgniter\Model;

 class NewsModel extends Model
@@ -10,6 +11,8 @@ class NewsModel extends Model

     protected $allowedFields = ['title', 'slug', 'body'];

+    protected $returnType = News::class;
+
     public function getNews($slug = false)
     {
         if ($slug === false) {

これで、検索結果が配列からEntityのインスタンスに変わります。

Newsコントローラの変更

検索結果が配列からEntityのインスタンスになったので、配列のキーをプロパティ名に変更します。

--- a/app/Controllers/News.php
+++ b/app/Controllers/News.php
@@ -2,6 +2,7 @@

 namespace App\Controllers;

+use App\Entities\News as NewsEntity;
 use App\Models\NewsModel;
 use CodeIgniter\Controller;

@@ -31,7 +32,7 @@ class News extends Controller
             throw new \CodeIgniter\Exceptions\PageNotFoundException('Cannot find the news item: ' . $slug);
         }

-        $data['title'] = $data['news']['title'];
+        $data['title'] = $data['news']->title;

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

新規Entityの保存は、Entityのインスタンスを作成し、それを save() します。

@@ -46,11 +47,12 @@ class News extends Controller
             'title' => 'required|min_length[3]|max_length[255]',
             'body'  => 'required',
         ])) {
-            $model->save([
+            $news = new NewsEntity([
                 'title' => $this->request->getPost('title'),
                 'slug'  => url_title($this->request->getPost('title'), '-', true),
                 'body'  => $this->request->getPost('body'),
             ]);
+            $model->save($news);

             echo view('news/success');
         } else {

Viewの変更

ビューも配列のキーをオブジェクトのプロパティに変更します。

--- a/app/Views/news/overview.php
+++ b/app/Views/news/overview.php
@@ -4,12 +4,12 @@

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

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

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

     <?php endforeach ?>

--- a/app/Views/news/view.php
+++ b/app/Views/news/view.php
@@ -1,2 +1,2 @@
-<h2><?= esc($news['title']) ?></h2>
-<p><?= esc($news['body']) ?></p>
+<h2><?= esc($news->title) ?></h2>
+<p><?= esc($news->body) ?></p>

これで、変更完了です。

参考

Tags: codeigniter, codeigniter4, database