FuelPHP のバリデーションについてです。標準では文字長でのバリデーションが用意されています。core/classes/validation.phpでは、
public function _validation_min_length($val, $length)
{
return $this->_empty($val) || (MBSTRING ? mb_strlen($val) : strlen($val)) >= $length;
}
というように、min_length, max_length, exact_length が用意されています。これらは、マルチバイト文字を1文字と判定して文字長を決めます。もちろんこの形式が望ましい場合が多いでしょうけど、画面表示などで使う文字列の場合、文字幅のほうが望ましい場合があるかもしれません。
FuelPHP 本体には無いようなので、つくってみました。
class MbWidthValidation
{
/**
* Minimum string width
*
* @param string
* @param int
* @return bool
*/
public static function _validation_min_width($val, $length)
{
return Validation::_empty($val) || (MBSTRING ? mb_strwidth($val) : strlen($val)*2) >= $length;
}
/**
* Maximum string width
*
* @param string
* @param int
* @return bool
*/
public static function _validation_max_width($val, $length)
{
return Validation::_empty($val) || (MBSTRING ? mb_strwidth($val) : strlen($val)*2) <= $length;
}
/**
* Exact string width
*
* @param string
* @param int
* @return bool
*/
public static function _validation_exact_width($val, $length)
{
return Validation::_empty($val) || (MBSTRING ? mb_strwidth($val) : strlen($val)*2) == $length;
}
}
長さ判定は、mb_strwidthを使っています。全角文字=2、半角文字=1として判定します。
テストコードは下記です。
/**
* Test_MbWidthValidation
*
* @group App
*/
class Test_MbWidthValidation extends TestCase
{
/**
* Validation: min_width
* Expecting: success
*
*/
public function test_validation_min_width_success()
{
$input = 'あ';
$output = MbWidthValidation::_validation_min_width($input,2);
$expected = true;
$this->assertEquals($expected, $output);
}
/**
* Validation: min_width
* Expecting: failure
*
*/
public function test_validation_min_width_failure()
{
$input = 'あo';
$output = MbWidthValidation::_validation_min_width($input,4);
$expected = false;
$this->assertEquals($expected, $output);
}
/**
* Validation: max_width
* Expecting: success
*
*/
public function test_validation_max_width_success()
{
$input = 'あ';
$output = MbWidthValidation::_validation_max_width($input,4);
$expected = true;
$this->assertEquals($expected, $output);
}
/**
* Validation: max_width
* Expecting: failure
*
*/
public function test_validation_max_width_failure()
{
$input = 'あo';
$output = MbWidthValidation::_validation_max_width($input,2);
$expected = false;
$this->assertEquals($expected, $output);
}
/**
* Validation: exact_width
* Expecting: success
*
*/
public function test_validation_exact_width_success()
{
$input = 'あ';
$output = MbWidthValidation::_validation_exact_width($input,2);
$expected = true;
$this->assertEquals($expected, $output);
}
/**
* Validation: exact_width
* Expecting: failure
*
*/
public function test_validation_exact_width_failure()
{
$input = 'あo';
$output = MbWidthValidation::_validation_exact_width($input,4);
$expected = false;
$this->assertEquals($expected, $output);
}
}
FuelPHP の本体のコードが、mb_strlen($val) という形で、文字エンコーディング指定が無いのですが、指定しておいたほうが良いかもしれません。