本記事では、独自に作成したフォームからデータを送信する際に、そのデータが適切な形式かチェックする仕組み(バリデーション)を設ける方法について紹介します。


このチェック機能を実装することで、入力してほしくない形式でのデータ送信を防ぐことができます。データベースに値を登録する場合においては、無用なエラーを阻止することにも繋がりますね。
なお、上記画像のようなメーカー情報登録ページ(およびメーカー情報を保存するためのテーブル)は以下記事にて作成しています。
- 【EC-CUBE 4】オリジナルテーブルをデータベースに新規で追加する方法
(メーカー情報を保存できるテーブル・『dtb_maker』を作成します。) - 【EC-CUBE 4】オリジナルテーブルに新規データ(レコード)を追加する方法
(上記で作成した『dtb_maker』に、Webページからフォームを送信してレコードを追加できるようにします。) - 【EC-CUBE 4】フォーム生成を別ファイル(FormType)に切り分ける
(フォームを生成するためのフォームタイプ・『MakerType.php』を作成します。)
本記事では、これらの記事で作成したフォームタイプ(MakerType.php)とコントローラ(MakerRegisterController.php)を修正する形で解説しています。
デバッグモードを設定しておくと、エラーが起きたときに詳細情報が表示されるようになります。
エラー箇所を探しやすくなるので、開発前に設定しておくのをオススメします。
デバッグモードの設定方法については 以下記事 で解説しています。
カスタマイズ後は、デバッグモードの解除を忘れないように。
未入力の場合、デフォルトでフォームが送信されないようになっている
そもそもEC-CUBEが採用しているPHPフレームワーク(Symfony)では、フォームが未入力の場合には値が送信されないような設定になっています。
お問い合わせなどのデフォルトで用意されたページを除き、自作したフォームを未入力で送信しようとすると、以下のような画面が表示されます。

なぜこのようになるのかというと、フォームを生成する段階(addメソッドで項目を追加するとき)に、そのフィールドを必須項目として設定するためです。
この必須機能をオフにしたい場合は、対象フィールドのaddメソッドを以下のように修正します。
add('name', TextType::class, [
'label' => 'メーカー名',
'required' => false,
)]3行目の'required'というオプションが、入力必須機能のオン・オフを制御しています。デフォルトでは'required' => trueなので、未入力OKにする場合はこれをfalseにします。
requiredオプションについてrequired オプションはHTMLのrequired属性に対応しており、ブラウザのクライアントサイドで未入力を制御します(JavaScriptが有効な場合)。ただし、あくまでクライアントサイドの制御なので、サーバーサイドでバリデーションを設定している場合(@Assert\NotBlank() など)は別途考慮が必要です。
EC-CUBEがはじめから用意しているフォームで必須機能を実装する場合は少し特殊なので、以下記事に別で纏めています。
複雑な入力規制を設定できるconstraints
入力が必須かどうかは'required'オプションで制御できますが、文字数制限をかけたりエラーメッセージを変えたりする場合は、'constraints'オプションを使います。
このオプションを使うと、フォーム送信時に設定したルールに従う場合と従わない場合で条件分岐ができるので、表示内容やデータベースへの反映を制御できるようになります。
required-
クライアントサイド(ブラウザ側) の必須入力を制御し、HTMLの
required属性を設定する。 constraints-
サーバーサイド(Symfonyのバリデーション) で適用され、PHPのバリデーションルールとして動作する。
'constraints'の基本的な使い方
'required'と同様に、対象フィールドのaddメソッドに'constraints'を設定するのですが、事前に以下のクラスをuseで読み込み、Assertで使えるようにしておきます。
use Symfony\Component\Validator\Constraints as Assert;addメソッドへの記述は、ルールに以下のように行います。
->add('name', TextType::class, [
'label' => 'メーカー名',
'constraints' => [
// 未入力のときにエラー(false)を返す
new Assert\NotBlank([
'message' => '入力してください。'
]),
// 入力文字数が少ない(2文字以下) もしくは 多いとき(13文字以上)にエラー(false)を返す
new Assert\Length([
'min' => 3, 'max' => 12,
'minMessage' => '3文字以上で入力してください。',
'maxMessage' => '12文字以下で入力してください。',
]),
]
])new Assert\Length() で 最小・最大文字数を制限できるようになります。また、message や minMessage などを指定することで、エラーメッセージのカスタマイズもできます。
Constraintsの代表的なバリデーション一覧
NotBlank / 空の値を許容しない(空白のみの入力もNG)
new Assert\NotBlank([
'message' => 'この項目は必須です。'
])NotNull / null を許容しない(空文字はOK)
new Assert\NotNull([
'message' => 'この項目は空にできません。'
])Length / 最小・最大文字数を制限
new Assert\Length([
'min' => 5, 'max' => 50,
'minMessage' => '5文字以上で入力してください。',
'maxMessage' => '50文字以下で入力してください。'
])Regex / 正規表現でチェック
new Assert\Regex([
'pattern' => '/^[a-zA-Z0-9]+$/',
'message' => '英数字のみ入力してください。'
])Email / メールアドレスの形式チェック
new Assert\Email([
'message' => '有効なメールアドレスを入力してください。'
])Url / URLの形式チェック
new Assert\Url([
'message' => '有効なURLを入力してください。'
])Date / 正しい日付かどうかをチェック
new Assert\Date([
'message' => '有効な日付を入力してください。'
])Positive / 正の数のみ許可
new Assert\Positive([
'message' => '正の数を入力してください。'
])Integer / 整数のみ許可
new Assert\Type([
'type' => 'integer',
'message' => '整数を入力してください。'
])| 入力必須 | NotBlank, NotNull |
|---|---|
| 文字列 | Length, Regex, Email, Url |
| 数値 | Range, GreaterThan, LessThan, Positive, Negative, Integer |
| 配列 | Choice, Count |
| 日時 | Date, DateTime, Time |
| ネットワーク | Ip, Uuid |
| カスタム | Callback |
他にも様々なルールを適用できる constraints が用意されているので、ぜひ調べてみてください!
Controllerで条件分岐を行い、ルールに合わない場合の処理を記述
フォーム側(MakerType.php)の記述が完了したら、Controller(MakerRegisterController.php)で条件分岐を行います。こちらの記事 で作成した、以下Controllerを改めて確認します。
<?php
namespace Customize\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Eccube\Controller\AbstractController;
use Customize\Entity\Maker;
use Doctrine\ORM\EntityManagerInterface;
use Customize\Form\Type\MakerType;
class MakerRegisterController extends AbstractController
{
/**
* @Route("/maker_register", name="maker_register")
* @Template("maker_register.twig")
*/
public function create(Request $request, EntityManagerInterface $entityManager)
{
$maker = new Maker();
$form = $this->createForm(MakerType::class, $maker);
if ($request->isMethod('POST')) {
$form->handleRequest($request);
// $form->isValid()には、constraintsでセットしたルールに従う場合はtrue、従わない場合はfalseが返る。
if ($form->isSubmitted() && $form->isValid()) {
// ルールに従う場合の処理
$entityManager->persist($maker);
$entityManager->flush();
return [
'message' => '登録完了しました!',
'form' => $form->createView(),
];
} else {
// ルールに従わない場合の処理
return [
'message' => '入力に誤りがあります。',
'form' => $form->createView(),
];
}
}
return [
'message' => 'メーカー情報を新規登録します。',
'form' => $form->createView(),
];
}
}if ($form->isSubmitted() && $form->isValid()) {以降の記述が、フォームを送信した際の条件分岐です。
$form->isValid()には、constraintsでセットしたルールに従う場合はtrue、従わない場合はfalseが返ります。
したがって、『フォームが送信され($form->isSubmitted())かつ入力ルールに合う($form->isValid())』場合に、データベースへの反映処理を記述してあげればOKです。
まとめ
以上、フォームにバリデーションを設定する方法について紹介しました。
入力内容が不適切な場合に処理を変えたい場合には、ぜひ使ってみてください。

