1

PHP has many built-in functions to validate numbers but they all expect input in computer format: 1234.56. I need to validate stuff like 1,234.56 (English) or 1.234,56 (Spanish), together with some typical attributes (accepted range, max number of decimals, etc.).

I started writing my own function but I soon got lost. It's easy to read the user input into a float variable but I want to be able to detect numbers with invalid formats like 1,23456.7 or 1..25.

Do you have any recommendation on the subject?

(Decimal and thousand characters are known beforehand and it's okay to hard-code digit groups as three, there's no need to cover Indian number format.)

Álvaro González
  • 142,137
  • 41
  • 261
  • 360

5 Answers5

3

Check out NumberFormatter::parse. You can parse numbers in a lot of locales with it. The whole intl extension is useful, even though it is not quite "there" yet.

janmoesen
  • 7,910
  • 1
  • 23
  • 19
1

I found an interesting function in a comment in the php manual : http://fr2.php.net/manual/en/language.types.float.php#92885 Have a look.

greg0ire
  • 22,714
  • 16
  • 72
  • 101
  • Although not applied directly to my problem, it's a witty approach. Too bad I got scared of setlocale() after suffering from some bugs in the Windows implementation. – Álvaro González May 31 '10 at 10:35
1

You can use regular expressions to validate numbers:

$ds = '.'; // Decimal separator
$ts = ','; // Thousand separator

$isValidFloat = preg_match(
    '/^

         # Integer part, one of the two allowed formats:
         # 1) with thousand separator, grouped by 3 digits
         # 2) without thousand separator
         (\d{1,3}(' . preg_quote($ts) . '\d{3})* | \d+)

         # Optional decimal part
         (' . preg_quote($ds) . '\d+)?

    $/x', $string);

And convert it to a float like this:

$float = (float) strtr($string, array($ts => '', $ds => '.'));
Alexander Konstantinov
  • 5,406
  • 1
  • 26
  • 31
1

In addition to the given solutions, I'd recommend the PEAR Validation package for validating numbers.

Here's an example from their site:

<?php
require_once 'Validate.php';

$number = '-8,1';
if (Validate::number($number,
    array('decimal' => '.,', 'min' => -9, 'max' => -7 ))) {
    echo 'Valid';
} else {
    echo 'Invalid';
}

If you want to be stricter on the format then you could parse it as a float (which you have done), and then use number_format to output the float into the formats you accept, and try to match the original format against any of the ones you have generated.

mqchen
  • 4,195
  • 1
  • 22
  • 21
-1

You perform all your calculations and for the result variable, you could use the built-in function number_format to format it as per your requirements.

Sarfraz
  • 377,238
  • 77
  • 533
  • 578
  • I don't want to convert from float to string. I want to validate whether a string contains a valid number in national format. `12.345` is a valid number but I can't store it in a DECIMAL(4,2) column. `1000` is a valid number but not a valid discount. – Álvaro González May 31 '10 at 09:53