シムノート

PHPフレームワークSymfonyの学習帳

ユーザ用ツール

サイト用ツール


サイドバー

メニュー



このエントリーをはてなブックマークに追加

blog:2015-12-14:超入門_symfony3_validation

超入門 Symfony3 : (8) Validation

SymfonyのValidation(検証)を試してみます。

Validationのサンプル

UnseiControllerを追加して、実験用のアクションメソッドvalidateActionを追加します。

<?php
namespace AppBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Response;
use AppBundle\Entity\Unsei;

/**
 * @Route("/unsei")  // ①
 */
class UnseiController extends Controller
{
    /**
     * @Route("/validate/{name}", defaults={"name" = ""}) // ②
     */
    public function validateAction($name)
    {
        $unsei = new Unsei();   // ③
        $unsei->setName($name);

        $validator = $this->get('validator');    // ④
        $errors = $validator->validate($unsei);  // ⑤

        if (count($errors) > 0) {
            return $this->render('unsei/validate.html.twig', [ // ⑥
                'errors' => $errors,
            ]);
        }

        return new Response("「{$name}」は正しい運勢です!"); // ⑦
    }
}

① いままで@Routeアノテーションはアクションメソッドに対して定義していましたが、ここではコントローラにも定義してます。 コントローラに@Routeがある場合、アクションメソッドのルートパスは「コントローラのルート + アクションメソッドのルート」(上記の① + ②)となります。その結果、②のルートパスは/unsei/validate/{name}になります。

② ルートパラメータでnameを受け取るルートを定義します。nameのデフォルト値も設定します。
unseiエンティティを生成し、ルートパラメータで受け取ったnameをセットします。
validatorサービスを取得します。
validatorで先ほど生成したunseiを検証します。
⑥ エラーがあれば、validate.html.twigにエラーメッセージを渡して表示します。
⑦ エラーが無い時の表示です。

次にvalidate.html.twigを作成します。

{% extends 'base.html.twig' %}

{% block title %}運勢の検証{% endblock %}

{% block body %}
<h3>運勢の検証でエラーがありました</h3>
<ul>
{% for error in errors %}
    <li>{{ error.message }}</li> {# ① #}
{% endfor %}
</ul>

{{ dump(errors) }}
    
{% endblock %}

① エラーメッセージを表示します。

ここで動作確認をしてみます。以下のどちらにアクセスしてもエラーは表示されません。

Constraints(制約)の設定

validatorはオブジェクトの制約(ルール)を使って検証を行います。Unseiエンティティに制約を定義してみましょう。

...
use Symfony\Component\Validator\Constraints as Assert; // (a)

/**
 * Unsei
 *
 * @ORM\Table(name="unsei")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\UnseiRepository")
 */
class Unsei
{
    ...

    /**
     * @ORM\Column(name="name", type="string")
     * 
     * @Assert\NotBlank() // ①
     */
    private $name;

    ...    
}

① アノテーションを使ってnameプロパティにNotBlank制約を追加しました。(a)でConstraintsネームスペースをインポートしてAssertとして別名を付けるのを忘れないで下さい。

ここで再度、動作確認を行います。以下のURLにアクセスします。

  1. http://localhost:8000/unsei/validate : NotBlankに違反する為、エラーが表示されます。
  2. http://localhost:8000/unsei/validate/大吉 : エラーにはなりません。

さらに、もう一つ制約を追加してみましょう。

...
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; // (a)

/**
 * Unsei
 *
 * @ORM\Table(name="unsei")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\UnseiRepository")
 * 
 * @UniqueEntity("name") // ①
 */
class Unsei
{
    ...

    /**
     * @ORM\Column(name="name", type="string", unique=true) // ②
     * 
     * @Assert\NotBlank()
     */
    private $name;

    ...    
}

UniqueEntity制約を追加します。UniqueEntityはクラスに対して付与する制約です。
nameプロパティのORMマッピング情報にuniqueを指定します。

ORMマッピング情報を変更したので、consoleコマンドを使ってDBスキーマを変更します。

$ php bin/console doctrine:schema:update --force

Updating database schema...

DBスキーマーを確認してみましょう。

$ sqlite3 var/data.db3

sqlite> .schema
CREATE TABLE unsei (id INTEGER NOT NULL, name VARCHAR(255) NOT NULL COLLATE BINARY, PRIMARY KEY(id));
CREATE UNIQUE INDEX UNIQ_56BA88855E237E06 ON unsei (name);

nameカラムにUNIQUE INDEXが作成されたことが分かります。

ここで再度、動作確認を行います。以下のURLにアクセスします。

  1. http://localhost:8000/unsei/validate : NotBlankに違反する為、エラーが表示されます。
  2. http://localhost:8000/unsei/validate/大吉 : UniqueEntityに違反する為、エラーが表示されます。
  3. http://localhost:8000/unsei/validate/ぴょん吉 : UniqueEntityに違反しないので、エラーにはなりません。

Constraints一覧

Symfonyでは一般的に必要とされる様々な制約を提供しています。

詳細はこちらを参照してください。

エラーメッセージの日本語化

日本語のバリデーションメッセージはSymfonyに含まれています。以下のようにconfig.ymlを修正することで表示することができます。

...

parameters:
    # en -> ja 変更します
    locale: ja

framework:
    # コメントアウトして有効にします
    translator:      { fallbacks: ["%locale%"] }
...

もう一度、以下のURLにアクセスして、動作確認を行ってみましょう。今度は日本語でエラーメッセージが表示されます。

  1. http://localhost:8000/unsei/validate : NotBlankに違反する為、エラーが表示されます。
  2. http://localhost:8000/unsei/validate/大吉 : UniqueEntityに違反する為、エラーが表示されます。

ValidationとForm

ここでは、実験用のアクションメソッドを作成して、Validationの基本を試しました。しかし、Validatorを直接使うことは少ないでしょう。多くの場合、ValidationはSymfonyのFormを使って行います。Formは内部でValidatorを使用し、検証やエラーメッセージの表示を行います。詳細は次回の「Form【前編】」を参照してください。


Comments



144 -4 = ?
blog/2015-12-14/超入門_symfony3_validation.txt · 最終更新: 2015/12/24 03:10 by tsubo