Validating number precision/scale
How would I validate the precision/scale of a number posted from a form to make sure it can be stored in an Oracle NUMBER column? For example:
<input type="number" name="foo" value="123.45" />
The user submits the form to the PHP backend...
<?php
function isValidNumber($number, $precision, $scale) {
// ???
return $isValid;
}
// The precision and scale here are actually dynamic
$isValid = isValidNumber($_POST['foo'], 5, 2);
...where I would like to be able to validate the number without trying to insert/update it in Oracle and handle any precision overflow errors (proactive design, rather than reactive). I have not been开发者_运维百科 able to come up with a method of accurately validating all the various fringe cases (Oracle doesn't produce errors for scale overflow - it just rounds to the maximum, but this rounding could lead to precision overflows, which do produce errors, etc.).
function isValidNumber($number, $precision, $scale) {
$isValid = false;
if (is_numeric($number)) {
$num = round(abs($number), $scale);
$max = str_repeat('9',$precision - $scale).'.'.str_repeat('9',$scale);
$isValid = $num <= $max;
}
return $isValid;
}
Output for isValidNumber($number, 5, 2)
123.456 (valid)
9999.999 (invalid)
99999.999 (invalid)
12.003 (valid)
999.99 (valid)
999.999 (invalid)
1234.5 (invalid)
and finally
isValid(1234567890123456789012345678.90, 30, 2) == **valid**
You can achieve this using n number of ways. Following can be starting point
- Client Side validation using HTML5 validation
A suggested way can be using Regex pattern based matches using HTML5 only.
input type="text" pattern="regex"
Disclaimer : the pattern logic has not been tested, so you will have to test it before you use anywhere
-?([0-9]{0,precision-scale}\.[0-9]{1,scale}|[0-9]{1,precision-scale})
the same Regex logic can also be used at any of the following layers which have there own plus and minus
- Client Side using Java-script Validation
- Server Side using php validation
- Validation at DB layer and throwing error all across different
layers
Get the length of the string , get the position of the decimal this will give you the total decimal places
$len = strlen($num);
$p = strpos($num, '.');
$dec_plcs = ($len - $p) - 1;
精彩评论