Laravel バリデーションについてまとめていくよ2(文字種編)

Laravel バリデーションについてまとめていくよ1に続いてlaravelのバリデーションをまとめていきます。
今回は、文字種についてのバリデーションを確認します。

確認するルールはalphaalpha_dashalpha_numasciistringlowercaseuppercasebooleanarrayです。

laravel/frameworkのバージョンはv9.45.1です。
参考までに、バリデーションの実装部分のソースのリンクもつけておきます。
実装部分の前に行われる処理もありますので、注意してください。

alpha | 英字

英字(アルファベット)のみ 文字であることをチェックします。
日本語などの全角文字にもtrueを返すので、注意が必要です。(後述します)

$rules = ['parameter' => 'alpha'];

// 後述します
$data = ['parameter' => 'あいうえお'];
Validator::make($data, $rules)->passes(); // true

// リクエストにパラメーターが含まれていない
$data = [];
Validator::make($data, $rules)->passes(); // true

// null
$data = ['parameter' => null];
Validator::make($data, $rules)->passes(); // false

// 空文字
$data = ['parameter' => ''];
Validator::make($data, $rules)->passes(); // true

// 半角スペース
$data = ['parameter' => ' '];
Validator::make($data, $rules)->passes(); // true

// 空配列
$data = ['parameter' => []];
Validator::make($data, $rules)->passes(); // false

// 配列に値あり
$data = ['parameter' => ['a', 'b']];
Validator::make($data, $rules)->passes(); // false

// アルファベット
$data = ['parameter' => 'a'];
Validator::make($data, $rules)->passes(); // true

// 半角スペースを含む
$data = ['parameter' => 'a b'];
Validator::make($data, $rules)->passes(); // false

// 改行を含む
$data = ['parameter' => "a\r\nb"];
Validator::make($data, $rules)->passes(); // false

Laravelでの実装はこちら。
https://github.com/laravel/framework/blob/v9.45.1/src/Illuminate/Validation/Concerns/ValidatesAttributes.php#L336-L346

日本語を許してしまう理由

実装を確認すると、下記のようになっています。

return is_string($value) && preg_match('/^[\pL\pM]+$/u', $value);

正規表現に[\pL\pM]が使われています。これらは何を指しているのでしょうか。

答えはPHP: Unicode 文字プロパティ – Manualにありました。
\pLには「小文字アルファベット (Lower case letter)」、「擬似文字 (Modifier letter)」、「その他の文字 (Other letter)」、「タイトル文字 (Title case letter)」、「大文字アルファベット (Upper case letter)」が含まれることなります。
\pMには「修飾文字 (Spacing mark)」、「他の文字を囲むための文字 (Enclosing mark)」、「他の文字を修飾するための文字 (Non-spacing mark)」が含まれることなります。

具体的な文字はUnicode Character Categoriesの「Ll / Lowercase Letter」、「Lm / Modifier Letter」などから確認できます。

その他の文字 (Other letter)に含まれる文字はList of Unicode Characters of Category “Other Letter”で確認できますが、含まれる文字数は127,004文字となります。
これには日本語が含まれるので、先述のように「あいうえお」に対してもtrueが返ってきます。

代替策

アルファベット52文字のみを受け付けるようにしたい場合は、正規表現のルールでregex:/^[A-Za-z]+$/uとするしかないようです。

alpha_num | 英字と数字

alphaで許容される文字に含め、数字に関連する文字が許容されます。
alphaの時点で日本語が含まれてしまうので、使用する機会はないかと思いますので動作サンプルは省略します。

実装部分の抜粋は下記。

return preg_match('/^[\pL\pM\pN]+$/u', $value) > 0;

Laravelでの実装はこちら。
https://github.com/laravel/framework/blob/v9.45.1/src/Illuminate/Validation/Concerns/ValidatesAttributes.php#L364-L378

\pNが含まれるので、などの文字も許容されます。

代替策

アルファベット、数字のみを受け付けるようにしたい場合は、正規表現のルールでregex:/^[A-Za-z0-9]+$/uとなりますね。

alpha_dash | 英字とハイフン(ダッシュ)、下線、数字

alpha_numで許容される文字に含め、ハイフン(ダッシュ)、下線が許容されます。
動作サンプルは省略します。

実装部分の抜粋は下記。

return preg_match('/^[\pL\pM\pN_-]+$/u', $value) > 0;

Laravelでの実装はこちら。
https://github.com/laravel/framework/blob/v9.45.1/src/Illuminate/Validation/Concerns/ValidatesAttributes.php#L348-L362

代替策

正規表現のルールでregex:/^[A-Za-z0-9_-]+$/uとなりますね。

ascii | アスキー文字

7bitのアスキー文字であることをチェックします。
改行、タブも許容されます。
正規表現で表すと[\x09\x10\x13\x0A\x0D\x20-\x7E]の文字が対象となります。

$rules = ['parameter' => 'ascii'];

// リクエストにパラメーターが含まれていない
$data = [];
Validator::make($data, $rules)->passes(); // true

// null
$data = ['parameter' => null];
Validator::make($data, $rules)->passes(); // false

// 空文字
$data = ['parameter' => ''];
Validator::make($data, $rules)->passes(); // true

// 半角スペース
$data = ['parameter' => ' '];
Validator::make($data, $rules)->passes(); // true

// 空配列
$data = ['parameter' => []];
Validator::make($data, $rules)->passes(); // Exception(実行できません)

// 配列に値あり
$data = ['parameter' => ['a', 'b']];
Validator::make($data, $rules)->passes(); // Exception(実行できません)

// 数値
$data = ['parameter' => 1];
Validator::make($data, $rules)->passes(); // true(途中で文字列にキャストされます)

// アルファベット
$data = ['parameter' => 'a'];
Validator::make($data, $rules)->passes(); // true

// 半角スペースを含む
$data = ['parameter' => 'a b'];
Validator::make($data, $rules)->passes(); // true

// 改行を含む
$data = ['parameter' => "a\r\nb"];
Validator::make($data, $rules)->passes(); // true

// 全角文字
$data = ['parameter' => 'あ'];
Validator::make($data, $rules)->passes(); // false

Laravelでの実装はこちら。
https://github.com/laravel/framework/blob/v9.45.1/src/Illuminate/Validation/Concerns/ValidatesAttributes.php#L145-L155

最終的に実行される部分は下記になります。
https://github.com/voku/portable-ascii/blob/2.0.1/src/voku/helper/ASCII.php#L545-L569

string | 文字列

型が文字列であることをチェックします。

$rules = ['parameter' => 'string'];

// リクエストにパラメーターが含まれていない
$data = [];
Validator::make($data, $rules)->passes(); // true

// null
$data = ['parameter' => null];
Validator::make($data, $rules)->passes(); // false

// 空文字
$data = ['parameter' => ''];
Validator::make($data, $rules)->passes(); // true

// 半角スペース
$data = ['parameter' => ' '];
Validator::make($data, $rules)->passes(); // true

// 空配列
$data = ['parameter' => []];
Validator::make($data, $rules)->passes(); // false

// 数値
$data = ['parameter' => 1];
Validator::make($data, $rules)->passes(); // false

// 真偽値
$data = ['parameter' => true];
Validator::make($data, $rules)->passes(); // false

// アルファベット
$data = ['parameter' => 'a'];
Validator::make($data, $rules)->passes(); // true

// 全角文字
$data = ['parameter' => 'あ'];
Validator::make($data, $rules)->passes(); // true

Laravelでの実装はこちら。
https://github.com/laravel/framework/blob/v9.45.1/src/Illuminate/Validation/Concerns/ValidatesAttributes.php#L2121-L2131

lowercase | 小文字

入力された文字が小文字であることをチェックします。
入力値をmb_strtolowerで小文字に変換後、===による比較を行います。

$rules = ['parameter' => 'lowercase'];

// リクエストにパラメーターが含まれていない
$data = [];
Validator::make($data, $rules)->passes(); // true

// null
$data = ['parameter' => null];
Validator::make($data, $rules)->passes(); // false

// 空文字
$data = ['parameter' => ''];
Validator::make($data, $rules)->passes(); // true

// 半角スペース
$data = ['parameter' => ' '];
Validator::make($data, $rules)->passes(); // true

// 空配列
$data = ['parameter' => []];
Validator::make($data, $rules)->passes(); // Exception(実行できません)

// 数値
$data = ['parameter' => 1];
Validator::make($data, $rules)->passes(); // false (型が合わずにfalseとなる)

// 真偽値
$data = ['parameter' => true];
Validator::make($data, $rules)->passes(); // false

// アルファベット(小文字)
$data = ['parameter' => 'a'];
Validator::make($data, $rules)->passes(); // true

// アルファベット(大文字)
$data = ['parameter' => 'B'];
Validator::make($data, $rules)->passes(); // false

// アルファベット(大文字、小文字混在)
$data = ['parameter' => 'a B'];
Validator::make($data, $rules)->passes(); // false

// 数字
$data = ['parameter' => '1'];
Validator::make($data, $rules)->passes(); // true

// 全角文字
$data = ['parameter' => 'あ'];
Validator::make($data, $rules)->passes(); // true (小文字がないのでtrueが返る)

// ヶ(<a href="https://ja.wikipedia.org/wiki/%E3%83%B6" rel="noopener" target="_blank">https://ja.wikipedia.org/wiki/%E3%83%B6</a>)
$data = ['parameter' => 'ヶ'];
Validator::make($data, $rules)->passes(); // true

Laravelでの実装はこちら。
https://github.com/laravel/framework/blob/v9.45.1/src/Illuminate/Validation/Concerns/ValidatesAttributes.php#L1203-L1214

uppercase | 大文字

入力された文字が大文字であることをチェックします。
入力値をmb_strtoupperで大文字に変換後、===による比較を行います。

$rules = ['parameter' => 'uppercase'];

// リクエストにパラメーターが含まれていない
$data = [];
Validator::make($data, $rules)->passes(); // true

// null
$data = ['parameter' => null];
Validator::make($data, $rules)->passes(); // false

// 空文字
$data = ['parameter' => ''];
Validator::make($data, $rules)->passes(); // true

// 半角スペース
$data = ['parameter' => ' '];
Validator::make($data, $rules)->passes(); // true

// 空配列
$data = ['parameter' => []];
Validator::make($data, $rules)->passes(); // Exception(実行できません)

// 数値
$data = ['parameter' => 1];
Validator::make($data, $rules)->passes(); // false (型が合わずにfalseとなる)

// 真偽値
$data = ['parameter' => true];
Validator::make($data, $rules)->passes(); // false

// アルファベット(小文字)
$data = ['parameter' => 'a'];
Validator::make($data, $rules)->passes(); // false

// アルファベット(大文字)
$data = ['parameter' => 'B'];
Validator::make($data, $rules)->passes(); // true

// アルファベット(大文字、小文字混在)
$data = ['parameter' => 'a B'];
Validator::make($data, $rules)->passes(); // false

// 数字
$data = ['parameter' => '1'];
Validator::make($data, $rules)->passes(); // true

// 全角文字
$data = ['parameter' => 'あ'];
Validator::make($data, $rules)->passes(); // true (小文字がないのでtrueが返る)

// ヶ(<a href="https://ja.wikipedia.org/wiki/%E3%83%B6" rel="noopener" target="_blank">https://ja.wikipedia.org/wiki/%E3%83%B6</a>)
$data = ['parameter' => 'ヶ'];
Validator::make($data, $rules)->passes(); // true

Laravelでの実装はこちら。
https://github.com/laravel/framework/blob/v9.45.1/src/Illuminate/Validation/Concerns/ValidatesAttributes.php#L1216-L1227

boolean | 真偽値

真偽値であることをチェックします。
truefalse10"1""0"が許容されます。

$rules = ['parameter' => 'boolean'];

// リクエストにパラメーターが含まれていない
$data = [];
Validator::make($data, $rules)->passes(); // true

// null
$data = ['parameter' => null];
Validator::make($data, $rules)->passes(); // false

// 空文字
$data = ['parameter' => ''];
Validator::make($data, $rules)->passes(); // true

// 半角スペース
$data = ['parameter' => ' '];
Validator::make($data, $rules)->passes(); // true

// 空配列
$data = ['parameter' => []];
Validator::make($data, $rules)->passes(); // false

// 数値
$data = ['parameter' => -1];
Validator::make($data, $rules)->passes(); // false

$data = ['parameter' => 0];
Validator::make($data, $rules)->passes(); // true

$data = ['parameter' => 1];
Validator::make($data, $rules)->passes(); // true

$data = ['parameter' => 2];
Validator::make($data, $rules)->passes(); // false

// 真偽値
$data = ['parameter' => true];
Validator::make($data, $rules)->passes(); // true

$data = ['parameter' => false];
Validator::make($data, $rules)->passes(); // true

// アルファベット
$data = ['parameter' => 'a'];
Validator::make($data, $rules)->passes(); // false

$data = ['parameter' => 'true'];
Validator::make($data, $rules)->passes(); // false

$data = ['parameter' => 'false'];
Validator::make($data, $rules)->passes(); // false

// 数字
$data = ['parameter' => '-1'];
Validator::make($data, $rules)->passes(); // false

$data = ['parameter' => '0'];
Validator::make($data, $rules)->passes(); // true

$data = ['parameter' => '1'];
Validator::make($data, $rules)->passes(); // true

$data = ['parameter' => '2'];
Validator::make($data, $rules)->passes(); // false

// 全角文字
$data = ['parameter' => 'あ'];
Validator::make($data, $rules)->passes(); // false

Laravelでの実装はこちら。
https://github.com/laravel/framework/blob/v9.45.1/src/Illuminate/Validation/Concerns/ValidatesAttributes.php#L441-L453

array | 配列

配列であることをチェックします。
配列に含めることができるキーを指定します。
キーの存在が必須ではないので注意が必要です。

$rules = ['parameter' => 'array:name,role'];

// リクエストにパラメーターが含まれていない
$data = [];
Validator::make($data, $rules)->passes(); // true

// null
$data = ['parameter' => null];
Validator::make($data, $rules)->passes(); // false

// 空文字
$data = ['parameter' => ''];
Validator::make($data, $rules)->passes(); // true

// 半角スペース
$data = ['parameter' => ' '];
Validator::make($data, $rules)->passes(); // true

// 空配列
$data = ['parameter' => []];
Validator::make($data, $rules)->passes(); // true

// 配列に値あり
$data = ['parameter' => ['a', 'b']];
Validator::make($data, $rules)->passes(); // false

// 指定されたキーのみが存在する
$data = ['parameter' => ['name' => 'Taro', 'role' => 'manager']];
Validator::make($data, $rules)->passes(); // true

// 指定されたキーの一部が存在する
$data = ['parameter' => ['name' => 'Taro']];
Validator::make($data, $rules)->passes(); // true

// 指定されたキー以外が存在する
$data = ['parameter' => ['name' => 'Taro', 'department' => 'engineering']];
Validator::make($data, $rules)->passes(); // false

// 文字列
$data = ['parameter' => 'a'];
Validator::make($data, $rules)->passes(); // false

Laravelでの実装はこちら。
https://github.com/laravel/framework/blob/v9.45.1/src/Illuminate/Validation/Concerns/ValidatesAttributes.php#L380-L399

コメント

コメントはありません。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です