That's exactly what I was thinking of.. but wondered if someone could spare me an hour on programming myself 🙂
So, I went ahead and re-invented the horse - could you guys ride my horse and see if it bucks you off and email me if you have a problem.
Bottom line, is_numeric() is cool but I wasn't aware of a recursive function to auto-typecast an array using common sense on what user input might be - this seems to work.
//this accepts both arrays and non-arrays
function numeralize(&$a){
/*
Version 0.1 created 2008-09-26 by Samuel Fullman (sam.fullman at verizon.net)
-----------------------------------------------------------------------------
* Takes an array of typical submitted data and "numeralizes" it into the proper typecasts.
* This does not deal with the $ sign for currency which a user might add - that would be left as a string.
* This also does not deal with a % - might consider a flag to turn 75% into (float) .75
* comment out all the echo's when you're satisfied this works
If you modify the function please EMAIL ME so I can improve this!
*/
global $leaveExponentNotationAsString;
if(!isset($leaveExponentNotationAsString)) $leaveExponentNotationAsString=true;
if(is_array($a)){
foreach($a as $n=>$v){
if(is_array($v)){
numeralize(&$a[$n]);
}else{
//Note how I deal with commas, a comma in a number is always followed by exactly 3 numbers - sorry to think like an American here :) - you could modify this to use a . instead
if(is_numeric(preg_replace('/,([0-9]{3})/','$1',$v))){
//make the conversion
$v=preg_replace('/,([0-9]{3})/','$1',$v);
if(substr($v,0,1)=='+'){
//the + is problematic from a standpoint of user data submission. +50 could mean an entirely different thing than 50. By some conventions, +50 could mean "add 50 to what's there" whereas 50 would mean "set the value to 50". The - is less so since it MUST be used to denote a negative. Because it would be extremely rare that a user input would be +.. to indicate a positive numeric value, we leave any value with a + at the front as a string
//default: leave as string
echo 'case1: ' . $v . '<br />';
}else if(preg_match('/e/i',$v) && $leaveExponentNotationAsString){
//note "172E3" might be a product number or etc that the user doesn't want converted into 172000
echo 'case1b: '. $v . '<br />';
}else if(!preg_match('/\./',$v)){
//integer strictest case either nnn or -nnn. However we still first typecast as (float), NOT (int) because typecasting as (int) would lose the 'e03' if exponential part was present
echo 'case2: ' . $v . '<br />';
$a[$n]=(float)$v;
$a[$n]=(int)$a[$n];
}else{
//decimal by definition (possible exponential part present)
echo 'case3: ' . $v . '<br />';
$a[$n]=(float)$v;
}
}else{
echo 'case4: ' . $v . '<br />';
}
}
}
}else{
//this code exactly as above - see notes there
if(is_numeric(preg_replace('/,([0-9]{3})/','$1',$a))){
$a=preg_replace('/,([0-9]{3})/','$1',$a);
if(substr($a,0,1)=='+'){
echo 'case5: ' . $a . '<br />';
}else if(preg_match('/e/i',$a) && $leaveExponentNotationAsString){
echo 'case5b: '. $a . '<br />';
}else if(!preg_match('/\./',$a)){
echo 'case6: ' . $a . '<br />';
$a=(float)$a;
$a=(int)$a;
}else{
echo 'case7: ' . $a . '<br />';
$a=(float)$a;
}
}else{
echo 'case8: ' . $a . '<br />';
}
}
}
$a=array(
1=>'hello',
2=>'35e2',
3=>'35.6e2',
4=>array(
1=>'5',
2=>'77.3',
3=>'+77.33',
4=>'69.50000000',
5=>'five'
),
5=>'3,000'
);
numeralize($a);
echo '<pre>';
print_r($a);