LaravelのVaridatorでalphaルールはa-zではない

More than 1 year has passed since last update.


はじめに

Laravelのvalidatorにalphaというルールがあります。てっきりA-Zとa-zの事だと思って使ったら日本語などにもマッチするのではまりました。

ドキュメントには「フィールドが全部アルファベット文字であることをバリデートします。」(原文: "The field under validation must be entirely alphabetic characters.")とあるのですが...

検索するとそういうものだから独自のルールを定義するか正規表現使えとありますが、なんだか納得いかないですね。


調査

ソースを調べたら以下のようになっていました。

Illuminate/Validation/Concerns/ValidatesAttributes.php:

    /**

* Validate that an attribute contains only alphabetic characters.
*
* @param string $attribute
* @param mixed $value
* @return bool
*/

public function validateAlpha($attribute, $value)
{
return is_string($value) && preg_match('/^[\pL\pM]+$/u', $value);
}

つまり説明文からはaからzの大文字小文字のような印象をうけがちですが、ユニコードのプロパティでいうところのLetterとMarkなので、日本語を含む様々な言語の文字(アクセント記号とかウムラウトとかそういう類の記号も)がすべて含まれているのです。広い意味での「アルファベット」ということなのでしょう

alpha_numalpha_dashも同様でした。数字は0から9ではなくこれまたユニコードのNumberプロパティなので、ローマ数字や丸つき数字などいろいろなものが含まれます。


/**
* Validate that an attribute contains only alpha-numeric characters, dashes, and underscores.
*
* @param string $attribute
* @param mixed $value
* @return bool
*/

public function validateAlphaDash($attribute, $value)
{
if (! is_string($value) && ! is_numeric($value)) {
return false;
}

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

/**
* Validate that an attribute contains only alpha-numeric characters.
*
* @param string $attribute
* @param mixed $value
* @return bool
*/

public function validateAlphaNum($attribute, $value)
{
if (! is_string($value) && ! is_numeric($value)) {
return false;
}

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


まとめ

a-zや0-9でバリデーションしたいときは正規表現を使いましょう。


追記

ドキュメントのバグとしてissue出そうかと思ったのですが、調べたところすでに修正のPR(Clarify allowed characters in alpha, alpha_num and alpha_dash #3412)が出ていて、しかも却下されていました。これはどうにもならなそうですね...