ニュースアイテムの作成
これで、CodeIgniterを使用してデータベースからデータを読み取る方法を理解できましたが、まだデータベースに情報を書き込んでいません。このセクションでは、先に作成したニュースコントローラーとモデルを拡張して、この機能を追加します。
CSRFフィルターの有効化
フォームを作成する前に、CSRF保護を有効にしましょう。
**app/Config/Filters.php**ファイルを開き、$methods
プロパティを次のように更新します。
<?php
namespace Config;
use CodeIgniter\Config\BaseConfig;
class Filters extends BaseConfig
{
// ...
public $methods = [
'post' => ['csrf'],
];
// ...
}
これは、すべての**POST**リクエストに対してCSRFフィルターを有効にするように設定します。CSRF保護の詳細については、セキュリティライブラリを参照してください。
警告
$methods
フィルターを使用する場合は、一般的に自動ルーティング(レガシー)の無効化を行う必要があります。なぜなら自動ルーティング(レガシー)は、コントローラーへのアクセスに任意のHTTPメソッドを許可するため、予期しないメソッドでコントローラーにアクセスするとフィルターを回避される可能性があるからです。
ルーティングルールの追加
CodeIgniterアプリケーションにニュースアイテムを追加するには、**app/Config/Routes.php**ファイルにルールを追加する必要があります。ファイルに次の内容が含まれていることを確認してください。
<?php
// ...
use App\Controllers\News;
use App\Controllers\Pages;
$routes->get('news', [News::class, 'index']);
$routes->get('news/new', [News::class, 'new']); // Add this line
$routes->post('news', [News::class, 'create']); // Add this line
$routes->get('news/(:segment)', [News::class, 'show']);
$routes->get('pages', [Pages::class, 'index']);
$routes->get('(:segment)', [Pages::class, 'view']);
'news/new'
のルートディレクティブは'news/(:segment)'
のディレクティブの前に配置され、ニュースアイテムを作成するためのフォームが表示されるようにします。
$routes->post()
行は、POSTリクエストのルーターを定義します。URIパス**/news**へのPOSTリクエストのみに一致し、News
クラスのcreate()
メソッドにマップされます。
さまざまなルーティングの種類については、ルーティングルールの設定を参照してください。
フォームの作成
news/createビューファイルの作成
データベースにデータを入力するには、情報を保存できるフォームを作成する必要があります。つまり、タイトルとテキストの2つのフィールドを持つフォームが必要になります。モデルではタイトルからスラッグを導出します。
**app/Views/news/create.php**に新しいビューを作成します。
<h2><?= esc($title) ?></h2>
<?= session()->getFlashdata('error') ?>
<?= validation_list_errors() ?>
<form action="/news" method="post">
<?= csrf_field() ?>
<label for="title">Title</label>
<input type="input" name="title" value="<?= set_value('title') ?>">
<br>
<label for="body">Text</label>
<textarea name="body" cols="45" rows="4"><?= set_value('body') ?></textarea>
<br>
<input type="submit" name="submit" value="Create news item">
</form>
ここでは、見慣れないものが4つほどあるかもしれません。
session()
関数はセッションオブジェクトを取得するために使用され、session()->getFlashdata('error')
はCSRF保護に関連するエラーをユーザーに表示するために使用されます。ただし、デフォルトでは、CSRF検証チェックが失敗すると例外がスローされるため、まだ機能していません。失敗時のリダイレクトを参照してください。
validation_list_errors()
関数は、フォームヘルパーによって提供され、フォーム検証に関連するエラーを報告するために使用されます。
csrf_field()
関数は、一般的な攻撃を防ぐのに役立つCSRFトークンを含む非表示の入力を生成します。
set_value()
関数は、フォームヘルパーによって提供され、エラーが発生したときに古い入力データを表示するために使用されます。
ニュースコントローラー
News
コントローラーに戻ります。
フォームを表示するためのNews::new()の追加
最初に、作成したHTMLフォームを表示するメソッドを作成します。
<?php
namespace App\Controllers;
use App\Models\NewsModel;
use CodeIgniter\Exceptions\PageNotFoundException;
class News extends BaseController
{
// ...
public function new()
{
helper('form');
return view('templates/header', ['title' => 'Create a news item'])
. view('news/create')
. view('templates/footer');
}
}
フォームヘルパーをhelper()
関数でロードします。ほとんどのヘルパー関数は、使用前にヘルパーをロードする必要があります。
そして、作成されたフォームビューを返します。
ニュースアイテムを作成するためのNews::create()の追加
次に、送信されたデータからニュースアイテムを作成するメソッドを作成します。
ここでは3つのことを行います。
送信されたデータが検証ルールに合格したかどうかを確認します。
ニュースアイテムをデータベースに保存します。
成功ページを返します。
<?php
namespace App\Controllers;
use App\Models\NewsModel;
use CodeIgniter\Exceptions\PageNotFoundException;
class News extends BaseController
{
// ...
public function create()
{
helper('form');
$data = $this->request->getPost(['title', 'body']);
// Checks whether the submitted data passed the validation rules.
if (! $this->validateData($data, [
'title' => 'required|max_length[255]|min_length[3]',
'body' => 'required|max_length[5000]|min_length[10]',
])) {
// The validation fails, so returns the form.
return $this->new();
}
// Gets the validated data.
$post = $this->validator->getValidated();
$model = model(NewsModel::class);
$model->save([
'title' => $post['title'],
'slug' => url_title($post['title'], '-', true),
'body' => $post['body'],
]);
return view('templates/header', ['title' => 'Create a news item'])
. view('news/success')
. view('templates/footer');
}
}
上記のコードは多くの機能を追加します。
データの取得
最初に、フレームワークによってコントローラーに設定されているIncomingRequestオブジェクト$this->request
を使用します。
ユーザーからの**POST**データから必要なアイテムを取得し、$data
変数に設定します。
データの検証
次に、コントローラーによって提供されるヘルパー関数validateData()を使用して、送信されたデータの検証を行います。この場合、タイトルと本文のフィールドは必須であり、特定の長さである必要があります。
CodeIgniterには、上記のように強力な検証ライブラリがあります。検証ライブラリの詳細を参照してください。
検証に失敗した場合は、作成したばかりのnew()
メソッドを呼び出し、HTMLフォームを返します。
ニュースアイテムの保存
検証がすべてのルールに合格した場合は、$this->validator->getValidated()によって検証済みのデータを取得し、$post
変数に設定します。
NewsModel
がロードされ、呼び出されます。これにより、ニュースアイテムがモデルに渡されます。 save()メソッドは、主キーと一致する配列キーが見つかるかどうかによって、レコードの挿入または更新を自動的に処理します。
これには、新しい関数url_title()
が含まれています。この関数は、URLヘルパーによって提供され、渡された文字列を処理し、すべてのスペースをダッシュ(-
)に置き換え、すべてを小文字にします。これにより、URIの作成に最適な、きれいなスラッグが作成されます。
成功ページの返却
その後、ビューファイルがロードされ、成功メッセージを表示するために返されます。app/Views/news/success.phpにビューを作成し、成功メッセージを記述してください。
これは、次のようにシンプルにすることができます。
<p>News item created successfully.</p>
NewsModelの更新
残っているのは、モデルがデータを正しく保存できるように設定することだけです。使用されたsave()
メソッドは、主キーの存在に基づいて、情報を挿入する必要があるか、行が既に存在していて更新する必要があるかを判断します。この場合、id
フィールドは渡されていないため、news
テーブルに新しい行が挿入されます。
しかし、デフォルトでは、モデルの挿入および更新メソッドは、更新できるフィールドがわからないため、実際にはデータを保存しません。NewsModel
を編集して、$allowedFields
プロパティに更新可能なフィールドのリストを提供してください。
<?php
namespace App\Models;
use CodeIgniter\Model;
class NewsModel extends Model
{
protected $table = 'news';
protected $allowedFields = ['title', 'slug', 'body'];
}
この新しいプロパティには、データベースへの保存を許可するフィールドが含まれています。id
を除外していることに注意してください。これは、データベースで自動インクリメントされるフィールドであるため、ほとんどの場合、必要ないからです。これは、マスアサインメント脆弱性からの保護に役立ちます。モデルがタイムスタンプを処理している場合、それらも除外します。
ニュースアイテムの作成
CodeIgniterをインストールしたローカル開発環境にブラウザを向け、URLに/news/newを追加します。いくつかのニュースを追加し、作成したさまざまなページを確認してください。


おめでとうございます
最初のCodeIgniter4アプリケーションが完成しました!
下の図は、作成または変更したすべてのファイルを含むプロジェクトのappフォルダを示しています。
app/
├── Config
│ ├── Filters.php (Modified)
│ └── Routes.php (Modified)
├── Controllers
│ ├── News.php
│ └── Pages.php
├── Models
│ └── NewsModel.php
└── Views
├── news
│ ├── create.php
│ ├── index.php
│ ├── success.php
│ └── view.php
├── pages
│ ├── about.php
│ └── home.php
└── templates
├── footer.php
└── header.php