Checking characters from an array of inputs.
Moderator: General Moderators
Checking characters from an array of inputs.
I've had a look around these forums and php.net, but I haven't managed to find a simple solution to my problem.
I have created a very basic form, and all I want to do is check all of the inputs have characters a-z and 0-9, so that nobody can try anything funny by using < ' etc etc.
So say i wanted to check: firstname, surname, houseno, address, country, telephone number
for values: a-z, A-Z, 0-9
Thanks
I have created a very basic form, and all I want to do is check all of the inputs have characters a-z and 0-9, so that nobody can try anything funny by using < ' etc etc.
So say i wanted to check: firstname, surname, houseno, address, country, telephone number
for values: a-z, A-Z, 0-9
Thanks
- shiznatix
- DevNet Master
- Posts: 2745
- Joined: Tue Dec 28, 2004 5:57 pm
- Location: Tallinn, Estonia
- Contact:
somthing like this should work
this will strip out everything but numbers, letters, spaces, and underscores.
Code: Select all
$string = preg_replace('/\W+/', '', $string);Or ctype_alnum which returns true for letters and numbers
Code: Select all
if (ctype_alnum($value) {
return TRUE;
} else {
return FALSE;
}d11wtq created a great validation class
that did most of if it but missed the alpha numeric bit so I added it to my copy.
if this is wrong one of the great reger's around here will correct it i'm sure
that did most of if it but missed the alpha numeric bit so I added it to my copy.
Code: Select all
function isAlphaNumeric($input) {
if(preg_match('/^[a-zA-Z0-9]*$/', $input)) return true;
return false;
}//End isAlphaNumericI've had a go at this, but I'm not getting anywhere.
I've put a count in, so that if there is 1 or more errors somewhere a user is told no.
Will any of the above solutions make this simpler and easier? Oh yeah, and work?
This doesn't seem to work, there is a :space: in there, but it hasn't been picked up
I've put a count in, so that if there is 1 or more errors somewhere a user is told no.
Will any of the above solutions make this simpler and easier? Oh yeah, and work?
Code: Select all
$strings = array($title, $firsname, $middle, $surname, $address1, $address2, $city);
$error_count = 0;
foreach($strings as $value){
if(eregi('/[a-zA-Z0-9][]/', $value)){
//nothing
} else {
$error_count++;
}
}
if ($error_count > 0){
echo('no');
} else {
echo('yes');
}Code: Select all
foreach($strings as $value){
if(ctype_alnum($value)) {
//nothing
} else {
$error_count++;
}
}
if ($error_count > 0){
echo('no');
} else {
echo('yes');
}Code: Select all
foreach($strings as $value){
if(ereg("[^a-zA-Z0-9]", $value)){
$error_count++;
}
}That works a treat, thanks!matthijs wrote:The caret ^operator reverses the selection. So if value contains anything other then a-zA-Z0-9 then ereg returns true (1). You can add more characters to this if you want. Like spaces, underscores, etc.Code: Select all
foreach($strings as $value){ if(ereg("[^a-zA-Z0-9]", $value)){ $error_count++; } }
You can also use preg_match. I believe preg_match is faster
and safer (according to Ilia Alshanetsky in PHP architects guide to php security). Try the example from that book:
Code: Select all
foreach($strings as $value){
//if(ctype_alnum($value)) {
//if(ereg("[^a-zA-Z0-9]", $value)){
if(preg_match("/[^a-zA-Z0-9]/", $value)){
$error_count++;
}
}Code: Select all
<?php
if(ereg("[^-'A-Za-z0-9 \t\n]", "don't forget about \n secu-rity\0\\") )
{
echo 'Ereg returns true<br>';
}
else
{
echo 'Ereg returns false<br>';
}
if( preg_match("![^-'A-Za-z \t\n]!", "don't forget about \n secu-rity\0\\") )
{
echo 'Preg_match returns true<br>';
}
else
{
echo 'Preg_match returns false<br>';
}
?>- John Cartwright
- Site Admin
- Posts: 11470
- Joined: Tue Dec 23, 2003 2:10 am
- Location: Toronto
- Contact:
- feyd
- Neighborhood Spidermoddy
- Posts: 31559
- Joined: Mon Mar 29, 2004 3:24 pm
- Location: Bothell, Washington, USA
Let's find out.Jcart wrote:ctype_alnum() is in all likelyhood faster than preg_*
Code: Select all
<?php
$iterations = 10000;
$tests = array(
'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq' => true,
'This is exactly 64 bytes long, not counting the terminating byte' => false
);
$calls = array(
array('preg_match','#^[a-z0-9]*$#i'),
array('preg_match','#^[a-z0-9]+$#i'),
array('preg_match','#^[a-zA-Z0-9]*$#'),
array('preg_match','#^[A-z0-9]*$#'),
array('eregi','^[a-z0-9]*$'),
array('eregi','^[a-z0-9]+$'),
array('ereg','^[a-zA-Z0-9]*$'),
array('ereg','^[A-z0-9]*$'),
array('ctype_alnum'),
);
if(function_exists('bcadd'))
{
bcscale(20); // precision
function addTime(&$a,$b,$c)
{
$b = explode(' ', $b);
$c = explode(' ', $c);
$a = bcadd($a, bcadd(bcsub($c[0], $b[0]), bcsub($c[1], $b[1])));
}
function div($a, $b)
{
return bcdiv($a, $b);
}
}
else
{
function addTime(&$a,$b,$c)
{
$b = explode(' ', $b);
$c = explode(' ', $c);
$a += $c[0] - $b[0] + $c[1] - $b[1];
}
function div($a, $b)
{
return $a / $b;
}
}
function rendNumber($a)
{
$out = strval($a);
if(strpos('.',$out) !== false)
{
$out = rtrim($out, '.0');
}
if(func_num_args() > 1)
{
$arg = func_get_arg(1);
$out = number_format($out, $arg);
}
else
{
$out = number_format($out);
}
return $out;
}
function flash($var)
{
if($var === null)
{
return 'null';
}
elseif(is_array($var))
{
$c = 0;
$o = 'array(';
foreach($var as $k => $v)
{
$o .= ($c > 0 ? ',' : '') . ($k == $c ? '' : flash($k) . '=>') . flash($v);
$c++;
}
$o .= ')';
return $o;
}
elseif(is_scalar($var))
{
return var_export($var,true);
}
elseif(is_object($var))
{
return 'object ' . get_class($var);
}
elseif(is_resource($var))
{
return 'reference ' . get_resource_type($var);
}
else
{
return 'unknown';
}
}
$p = 8; // precision
$results = array();
foreach($tests as $test => $comp)
{
foreach($calls as $call)
{
$time = 0;
$func = array_shift($call);
array_push($call, $test);
for($i = 0; $i < $iterations; $i++)
{
$t1 = microtime();
$result = call_user_func_array($func, $call);
$t2 = microtime();
addTime($time, $t1, $t2);
}
$code = preg_replace('#^array(?=\()#i', $func, flash($call,true));
$pass = ($result == $comp ? 'PASS' : 'FAIL');
$result = flash($result);
array_push($results, array('code' => $code, 'result' => $result, 'pass' => $pass, 'time' => rendNumber($time, $p), 'avg' => rendNumber(div($time,$iterations), $p)));
}
}
$l = 0;
$c = strlen('Code');
$r = strlen('Result');
$p = strlen('Pass');
$t = strlen('Time');
$a = strlen('Average');
foreach($results as $result)
{
foreach($result as $key => $elem)
{
$$key = strlen($elem);
${$key{0}} = max($$key, ${$key{0}});
}
$l = max(2 + $code + 3 + $result + 3 + $pass + 3 + $time + 3 + $avg + 2, $l);
}
$line = '+' . str_repeat('-', $c + 2) . '+' . str_repeat('-', $r + 2) . '+' . str_repeat('-', $p + 2) . '+' . str_repeat('-', $t + 2) . '+' . str_repeat('-', $a + 2) . '+' . PHP_EOL;
echo rendNumber($iterations) . ' interation' . ($iterations != 1 ? 's' : '') . PHP_EOL;
echo $line;
printf("| %-{$c}s | %-{$r}s | %-{$p}s | %-{$t}s | %-{$a}s |" . PHP_EOL, 'Code', 'Result', 'Pass', 'Time', 'Average');
echo $line;
foreach($results as $result)
{
printf("| %-{$c}s | %{$r}s | %{$p}s | %{$t}s | %{$a}s |" . PHP_EOL, $result['code'], $result['result'], $result['pass'], $result['time'], $result['avg']);
}
echo $line;
?>Code: Select all
10,000 interations
+---------------------------------------------------------------------------------------------------+--------+------+------------+------------+
| Code | Result | Pass | Time | Average |
+---------------------------------------------------------------------------------------------------+--------+------+------------+------------+
| preg_match('#^[a-z0-9]*$#i','abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq') | 1 | PASS | 0.11596100 | 0.00001160 |
| preg_match('#^[a-z0-9]+$#i','abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq') | 1 | PASS | 0.11462300 | 0.00001146 |
| preg_match('#^[a-zA-Z0-9]*$#','abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq') | 1 | PASS | 0.11865000 | 0.00001187 |
| preg_match('#^[A-z0-9]*$#','abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq') | 1 | PASS | 0.11458500 | 0.00001146 |
| eregi('^[a-z0-9]*$','abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq') | 1 | PASS | 0.15699600 | 0.00001570 |
| eregi('^[a-z0-9]+$','abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq') | 1 | PASS | 0.14902200 | 0.00001490 |
| ereg('^[a-zA-Z0-9]*$','abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq') | 1 | PASS | 0.15475600 | 0.00001548 |
| ereg('^[A-z0-9]*$','abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq') | 1 | PASS | 0.15353700 | 0.00001535 |
| ctype_alnum('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq') | true | PASS | 0.09177500 | 0.00000918 |
| preg_match('#^[a-z0-9]*$#i','This is exactly 64 bytes long, not counting the terminating byte') | 0 | PASS | 0.12162800 | 0.00001216 |
| preg_match('#^[a-z0-9]+$#i','This is exactly 64 bytes long, not counting the terminating byte') | 0 | PASS | 0.11854600 | 0.00001185 |
| preg_match('#^[a-zA-Z0-9]*$#','This is exactly 64 bytes long, not counting the terminating byte') | 0 | PASS | 0.12182100 | 0.00001218 |
| preg_match('#^[A-z0-9]*$#','This is exactly 64 bytes long, not counting the terminating byte') | 0 | PASS | 0.12280300 | 0.00001228 |
| eregi('^[a-z0-9]*$','This is exactly 64 bytes long, not counting the terminating byte') | false | PASS | 0.16258800 | 0.00001626 |
| eregi('^[a-z0-9]+$','This is exactly 64 bytes long, not counting the terminating byte') | false | PASS | 0.14989100 | 0.00001499 |
| ereg('^[a-zA-Z0-9]*$','This is exactly 64 bytes long, not counting the terminating byte') | false | PASS | 0.16287400 | 0.00001629 |
| ereg('^[A-z0-9]*$','This is exactly 64 bytes long, not counting the terminating byte') | false | PASS | 0.16153800 | 0.00001615 |
| ctype_alnum('This is exactly 64 bytes long, not counting the terminating byte') | false | PASS | 0.08918900 | 0.00000892 |
+---------------------------------------------------------------------------------------------------+--------+------+------------+------------+Code: Select all
10,000 interations
+---------------------------------------------------------------------------------------------------+--------+------+------------+------------+
| Code | Result | Pass | Time | Average |
+---------------------------------------------------------------------------------------------------+--------+------+------------+------------+
| preg_match('#^[a-z0-9]*$#i','abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq') | 1 | PASS | 0.06220700 | 0.00000622 |
| preg_match('#^[a-z0-9]+$#i','abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq') | 1 | PASS | 0.06118600 | 0.00000612 |
| preg_match('#^[a-zA-Z0-9]*$#','abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq') | 1 | PASS | 0.06278200 | 0.00000628 |
| preg_match('#^[A-z0-9]*$#','abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq') | 1 | PASS | 0.06250400 | 0.00000625 |
| eregi('^[a-z0-9]*$','abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq') | 1 | PASS | 0.11453300 | 0.00001145 |
| eregi('^[a-z0-9]+$','abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq') | 1 | PASS | 0.10529900 | 0.00001053 |
| ereg('^[a-zA-Z0-9]*$','abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq') | 1 | PASS | 0.11655600 | 0.00001166 |
| ereg('^[A-z0-9]*$','abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq') | 1 | PASS | 0.11385300 | 0.00001139 |
| ctype_alnum('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq') | true | PASS | 0.05107100 | 0.00000511 |
| preg_match('#^[a-z0-9]*$#i','This is exactly 64 bytes long, not counting the terminating byte') | 0 | PASS | 1.06066100 | 0.00010607 |
| preg_match('#^[a-z0-9]+$#i','This is exactly 64 bytes long, not counting the terminating byte') | 0 | PASS | 0.06009300 | 0.00000601 |
| preg_match('#^[a-zA-Z0-9]*$#','This is exactly 64 bytes long, not counting the terminating byte') | 0 | PASS | 0.06421300 | 0.00000642 |
| preg_match('#^[A-z0-9]*$#','This is exactly 64 bytes long, not counting the terminating byte') | 0 | PASS | 0.06346500 | 0.00000635 |
| eregi('^[a-z0-9]*$','This is exactly 64 bytes long, not counting the terminating byte') | false | PASS | 0.12100700 | 0.00001210 |
| eregi('^[a-z0-9]+$','This is exactly 64 bytes long, not counting the terminating byte') | false | PASS | 1.10673000 | 0.00011067 |
| ereg('^[a-zA-Z0-9]*$','This is exactly 64 bytes long, not counting the terminating byte') | false | PASS | 0.12095500 | 0.00001210 |
| ereg('^[A-z0-9]*$','This is exactly 64 bytes long, not counting the terminating byte') | false | PASS | 0.12074500 | 0.00001207 |
| ctype_alnum('This is exactly 64 bytes long, not counting the terminating byte') | false | PASS | 0.04778800 | 0.00000478 |
+---------------------------------------------------------------------------------------------------+--------+------+------------+------------+I was just wondering if anybody could help me further, I've tried preg_match instead but I'm getting a strange result.
here is the code:
So if I type "kevin&" in to $firstname, is should fail verification and do action A, which it does
But if I type "kevin" in to $firstname and "williams" in to $surname, it should pass verification and do action B, but it doesn't, it does action A still.
Can anybody see where I'm going wrong?
here is the code:
Code: Select all
$strings = array($firstname, $surname);
$total_error = 0;
foreach($strings as $value){
if( preg_match("![^-'A-Za-z \t\n]!", $value)){
// do nothing
}else{
$total_error++;
}
}
if ($total_error > 0){
do action A
} else {
do action B
}But if I type "kevin" in to $firstname and "williams" in to $surname, it should pass verification and do action B, but it doesn't, it does action A still.
Can anybody see where I'm going wrong?
That's pretty cool Feyd.
Keveh, the preg_match has the ^ before the pattern. Try
The preg_match is doing something like "if the $value contains any characters other then A-Za-z \t\n then return true (echo bad characters in my example)
Try your script like this:
Keveh, the preg_match has the ^ before the pattern. Try
Code: Select all
$value = 'kevin&';
if( preg_match("![^-'A-Za-z \t\n]!", $value)){
echo 'Contains bad characters';
}Try your script like this:
Code: Select all
<?php
$firstname = 'kevin$';
$surname = 'williams';
$strings = array($firstname, $surname);
$total_error = 0;
foreach($strings as $value){
// if $value contains other characters the a-z etc
if( preg_match("![^-'A-Za-z \t\n]!", $value)){
$total_error++; // add an error
}
}
var_dump ($total_error);
if ($total_error > 0){
echo '<br>do action A<br>';
} else {
echo '<br>do action B<br>';
}
?>