Strlen issue for numbers

There is an issue you must keep in mind when dealing with PHP numeric types.

I was trying to validate a credit card number today, in order to apply Luhn’s algorithm I needed to know the number of digits in the credit card number string.

Let me give you an example:

Credit card number: 4415121641207182

Let’s say I’m using a function.

function luhnsFunc ($ccn){
    return strlen($ccn);
}

And call it like this:

$ccn = '4415121641207182';
echo luhnsFunc($ccn);

The returned value is: 16

But see what happens when the credit card number is not declared as a string.

$ccn = 4415121641207182; //No quotes
echo luhnsFunc($ccn);

The returned value is: 19

So what’s happening here?!

I did a var dump to each case and found out something pretty interesting.

For the first case I got:

string(16) "4415410012107183"

Which is ok, but let’s see the second case.

float(4.4154100121072E+15)

So it’s storing a float on scientific notation. Why?

Take a look at this:

http://www.php.net/manual/en/language.types.integer.php

Just above the warning you’ll read the following:

The size of an integer is platform-dependent, although a maximum value of about two billion is the usual value (that’s 32 bits signed). 64-bit platforms usually have a maximum value of about 9E18. PHP does not support unsigned integers. Integer size can be determined using the constant PHP_INT_SIZE, and maximum value using the constant PHP_INT_MAX since PHP 4.4.0 and PHP 5.0.5.

The purpose of creating the function is that no matter what I pass it as an argument it will always bring the correct result. Applying the Luhn’s algorithm to a 16 char length string is very different than applying it to a 19 chars length string.

So how do I solve this?

function luhnsFunc ($ccn){
    $type = gettype($ccn);
    switch($type){
        case 'string':
            break;
        default:
            $ccn = number_format($ccn,0,'',''); //The second parameter is a zero
            break;
    }
    return strlen($ccn);
}

An finally the length is correct

Tags:

Comments are closed.