Validation.

CakePHP3標準のバリデーション処理.

テーブルに紐付くEntityとTableクラス

データベースで適当なテーブルを作り、bakeコマンドでテーブルに紐付くクラスを生成.

namespace App\Model\Entity;

use Cake\ORM\Entity;

/**
 * MCompany Entity
 */
class MCompany extends Entity
{

    protected $_accessible = [
        '*' => true,
        'id' => false
    ];
}

Tableクラスではバリデーションを定義.

/**
 * MCompany Model
 */
class MCompanyTable extends Table
{

    /**
     * Initialize method
     */
    public function initialize(array $config)
    {
        parent::initialize($config);

        $this->table('m_companies');
        $this->displayField('id');
        $this->primaryKey('id');

        $this->addBehavior('Timestamp');

        $this->belongsTo('CreatedUsers', [
            'foreignKey' => 'created_user_id'
        ]);
        $this->belongsTo('ModifiedUsers', [
            'foreignKey' => 'modified_user_id'
        ]);
    }

    /**
     * Default validation rules.
     */
    public function validationDefault(Validator $validator)
    {
        $validator
            ->integer('id')
            ->allowEmpty('id', 'create');

        $validator
            ->requirePresence('company_code', 'create')
            ->notEmpty('company_code');

        $validator
            ->requirePresence('company_name', 'create')
            ->notEmpty('company_name');

        $validator
            ->integer('is_deleted')
            ->requirePresence('is_deleted', 'create')
            ->notEmpty('is_deleted');

        return $validator;
    }
}

項目全てにNotNull制約が付与されている.

バリデーションの呼び出し方

一度Entityを生成し、呼び出すバリデーションを指定.

namespace App\Shell;

use Cake\Console\Shell;

/**
 * Test shell command.
 */
class TestShell extends Shell
{
    //一部省略
    
    /**
     * Validation
     */
    public function valid()
    {
        $company = $this->MCompanies->newEntity(
            array(
                'id' => '1',
                'company_code' => '',
                'company_name' => 'test',
                'is_deleted' => '0'),
            array('validate' => 'Default'));
        if ($company->errors()) {
            $this->out("error");
        }
        $this->out("Finish");
    }
    
}

company_codeが空文字なので、実行結果は以下の通りとなる.

C:\xampp\htdocs\Cakephp>bin\cake test valid

Welcome to CakePHP v3.3.14 Console
--------------------------------------------------------
App : src
Path: C:\xampp\htdocs\Cakephp\src\
PHP : 7.1.1
--------------------------------------------------------
error
Finish

仮にバリデーションに引っかかった場合でも、Entityインスタンスは返却される.

値が適正だったかどうかは、$entity->errors()メソッドを介して確認が可能.

Entityを使わなくても、バリデーションは実行出来る.

namespace App\Shell;
 
use Cake\Console\Shell;
 
/**
 * Test shell command.
 */
class TestShell extends Shell
{
    //一部省略
     
    /**
     * Validation
     */
    public function valid()
    {

        $errors = $this->MCompanies->validator('Default')->errors(array(
            'id' => '1',
            'company_code' => '',
            'company_name' => 'test',
            'is_deleted' => '0'
        ));
        if (count($errors) !== 0) {
            // エラー処理
        }

バリデーションセットという概念

CakePHP3では幾つかの検証観点を、一つのまとまりとして定義することが出来る.

上記のように独自のバリデーションセットを作り、自由に呼び出すことが可能.

/**
 * Custom validation rules.
 */
public function validationCustom(Validator $validator)
{
    // defaultの検証内容を引き継ぐ
    $validator = $this->validationDefault($validator);

    // 検証内容の追加
    $validator
        ->alphaNumeric('company_code', '英数字で入力してね!!');

    return $validator;
}

ちなみにalphaNumericは半角英数字のみだが...

どうやら日本語は通してしまうので、日本のWebサービスでは使い物にならない.

default同様、Entity生成時に検証したいバリデーションメソッドを指定.

public function valid()
{
    $company = $this->MCompanies->newEntity(
        array(
            'id' => '1',
            'company_code' => '***',
            'company_name' => 'test',
            'is_deleted' => '0'),
        array('validate' => 'Custom'));
    if ($company->errors()) {
        $this->out("error");
    }
    $this->out("Finish");
}

実行結果は以下の通り↓↓↓

C:\xampp\htdocs\Cakephp>bin\cake test valid

Welcome to CakePHP v3.3.14 Console
--------------------------------------------------
App : src
Path: C:\xampp\htdocs\Cakephp\src\
PHP : 7.1.1
--------------------------------------------------
error
Finish

エラーメッセージなどは配列であるEntity内に格納されている.

Fin.