Skip to content

Commit ca93925

Browse files
committed
Add ascii() and utf8() validators.
These methods will let you confirm the byte ranges in an input. This is helpful when dealing with MySQL's utf8 encodings which do not support any 4 byte characters.
1 parent 2093755 commit ca93925

File tree

2 files changed

+125
-1
lines changed

2 files changed

+125
-1
lines changed

src/Validation/Validation.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1097,6 +1097,48 @@ public static function longitude($value, array $options = [])
10971097
return self::geoCoordinate($value, $options);
10981098
}
10991099

1100+
/**
1101+
* Check that the input value is within the ascii byte range.
1102+
*
1103+
* This method will reject all non-string values.
1104+
*
1105+
* @param string $value The value to check
1106+
* @return bool
1107+
*/
1108+
public static function ascii($value)
1109+
{
1110+
if (!is_string($value)) {
1111+
return false;
1112+
}
1113+
return strlen($value) <= mb_strlen($value, 'utf-8');
1114+
}
1115+
1116+
/**
1117+
* Check that the input value is a utf8 string.
1118+
*
1119+
* This method will reject all non-string values.
1120+
*
1121+
* # Options
1122+
*
1123+
* - `extended` - Disallow bytes higher within the basic multilingual plane.
1124+
* MySQL's older utf8 encoding type does not allow characters above
1125+
* the basic multilingual plane. Defaults to false.
1126+
*
1127+
* @param string $value The value to check
1128+
* @return bool
1129+
*/
1130+
public static function utf8($value, array $options = [])
1131+
{
1132+
if (!is_string($value)) {
1133+
return false;
1134+
}
1135+
$options += ['extended' => false];
1136+
if ($options['extended']) {
1137+
return true;
1138+
}
1139+
return preg_match('/[\x{10000}-\x{10FFFF}]/u', $value) === 0;
1140+
}
1141+
11001142
/**
11011143
* Check that the input value is an integer
11021144
*

tests/TestCase/Validation/ValidationTest.php

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2566,7 +2566,7 @@ public function testLongitude()
25662566
}
25672567

25682568
/**
2569-
* Test is_integer
2569+
* Test isInteger
25702570
*
25712571
* @return void
25722572
*/
@@ -2584,4 +2584,86 @@ public function testIsInteger()
25842584
$this->assertFalse(Validation::isInteger(new \StdClass));
25852585
$this->assertFalse(Validation::isInteger('2 bears'));
25862586
}
2587+
2588+
/**
2589+
* Test ascii
2590+
*
2591+
* @return void
2592+
*/
2593+
public function testAscii()
2594+
{
2595+
$this->assertTrue(Validation::ascii('1 big blue bus.'));
2596+
$this->assertTrue(Validation::ascii(',.<>[]{;/?\)()'));
2597+
2598+
$this->assertFalse(Validation::ascii([]));
2599+
$this->assertFalse(Validation::ascii(1001));
2600+
$this->assertFalse(Validation::ascii(3.14));
2601+
$this->assertFalse(Validation::ascii(new \StdClass));
2602+
2603+
// Latin-1 supplement
2604+
$this->assertFalse(Validation::ascii('some' . "\xc2\x82" . 'value'));
2605+
$this->assertFalse(Validation::ascii('some' . "\xc3\xbf" . 'value'));
2606+
2607+
// End of BMP
2608+
$this->assertFalse(Validation::ascii('some' . "\xef\xbf\xbd" . 'value'));
2609+
2610+
// Start of supplementary multilingual plane
2611+
$this->assertFalse(Validation::ascii('some' . "\xf0\x90\x80\x80" . 'value'));
2612+
}
2613+
2614+
/**
2615+
* Test utf8 basic
2616+
*
2617+
* @return void
2618+
*/
2619+
public function testUtf8Basic()
2620+
{
2621+
$this->assertFalse(Validation::utf8([]));
2622+
$this->assertFalse(Validation::utf8(1001));
2623+
$this->assertFalse(Validation::utf8(3.14));
2624+
$this->assertFalse(Validation::utf8(new \StdClass));
2625+
$this->assertTrue(Validation::utf8('1 big blue bus.'));
2626+
$this->assertTrue(Validation::utf8(',.<>[]{;/?\)()'));
2627+
2628+
// Latin-1 supplement
2629+
$this->assertTrue(Validation::utf8('some' . "\xc2\x82" . 'value'));
2630+
$this->assertTrue(Validation::utf8('some' . "\xc3\xbf" . 'value'));
2631+
2632+
// End of BMP
2633+
$this->assertTrue(Validation::utf8('some' . "\xef\xbf\xbd" . 'value'));
2634+
2635+
// Start of supplementary multilingual plane
2636+
$this->assertFalse(Validation::utf8('some' . "\xf0\x90\x80\x80" . 'value'));
2637+
2638+
// Grinning face
2639+
$this->assertFalse(Validation::utf8('some' . "\xf0\x9f\x98\x80" . 'value'));
2640+
}
2641+
2642+
/**
2643+
* Test utf8 extended
2644+
*
2645+
* @return void
2646+
*/
2647+
public function testUtf8Extended()
2648+
{
2649+
$this->assertFalse(Validation::utf8([], ['extended' => true]));
2650+
$this->assertFalse(Validation::utf8(1001, ['extended' => true]));
2651+
$this->assertFalse(Validation::utf8(3.14, ['extended' => true]));
2652+
$this->assertFalse(Validation::utf8(new \StdClass, ['extended' => true]));
2653+
$this->assertTrue(Validation::utf8('1 big blue bus.', ['extended' => true]));
2654+
$this->assertTrue(Validation::utf8(',.<>[]{;/?\)()', ['extended' => true]));
2655+
2656+
// Latin-1 supplement
2657+
$this->assertTrue(Validation::utf8('some' . "\xc2\x82" . 'value', ['extended' => true]));
2658+
$this->assertTrue(Validation::utf8('some' . "\xc3\xbf" . 'value', ['extended' => true]));
2659+
2660+
// End of BMP
2661+
$this->assertTrue(Validation::utf8('some' . "\xef\xbf\xbd" . 'value', ['extended' => true]));
2662+
2663+
// Start of supplementary multilingual plane
2664+
$this->assertTrue(Validation::utf8('some' . "\xf0\x90\x80\x80" . 'value', ['extended' => true]));
2665+
2666+
// Grinning face
2667+
$this->assertTrue(Validation::utf8('some' . "\xf0\x9f\x98\x80" . 'value', ['extended' => true]));
2668+
}
25872669
}

0 commit comments

Comments
 (0)