1

I am dealing with data that involves very large primary keys (12 digits). When I try to put the data in an array in the form id => value, the index is not assigned properly.

$test = array(190337172011 => 'Apple');
print_r($test);

Result:

Array ( [1358610987] => Apple ) 

Sometimes it even results in a negative number. Why does this happen? Is it a bug?

I am running PHP 5.3.10 on IIS.

hakre
  • 193,403
  • 52
  • 435
  • 836
Mike
  • 155
  • 1
  • 6
  • 2
    Is this a 32 bit or 64 bit version of PHP? If it's a 32 bit platform, then you're going to run out of space storing those keys: http://php.net/manual/en/language.types.integer.php – Billy ONeal Apr 29 '12 at 01:40
  • See [this question](http://stackoverflow.com/q/467149/825789), looks like it's a memory issue. – bfavaretto Apr 29 '12 at 01:40
  • @bfavaretto: If it was too much memory, the script would be terminated; not return wrong results. – Billy ONeal Apr 29 '12 at 01:42
  • Thanks @BillyONeal, it's a 32 bit version of PHP, but I'm still a bit confused. If I reverse the key and value: `Array ( [Apple] => 190337172011 )` works fine. Isn't it still being stored as an integer either way? – Mike Apr 29 '12 at 01:54
  • @Billy I mean the amount of memory available to PHP (via `memory_limit` php.ini setting) determines the max value an array key can have -- according to the accepted answer to the question I linked to. – bfavaretto Apr 29 '12 at 02:03
  • ... but now I see that was about string keys... – bfavaretto Apr 29 '12 at 02:04

2 Answers2

2

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.

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

Hajo
  • 849
  • 6
  • 21
0

You are using a 32 bit PHP version on probably a 32 bit windows operating system, for example Windows XP.

For numerical array indexes PHP uses the integer variable type to store the keys. Those are limited. This limitation becomes visible if you choose a value greater than the limit which will either trigger a max or a turn-around depending on the PHP version and the operating system.

The value 190337172011 is too large of the integer type on your system, that's why you get a cap through roundtrip with a result of 1358610987. Roundtrip means, that after the possible maximum positive number, the next number is the lowest possible number, which is the "largest" negative number that can be expressed. That's why you get negative numbers as well.

You can work around that by storing the values as string keys which needs some pre-fixing:

$test = array('ID' . 190337172011 => 'Apple');
print_r($test);

This is normally enough to make your code more portable. You can choose any string prefix as you like, ID is just exemplary, but you need at least one non-numeric character.

hakre
  • 193,403
  • 52
  • 435
  • 836
  • Thanks for the explanation. I had noticed it also works to simply cast the id as a string when building the array. – Mike Apr 29 '12 at 16:59
  • Casting to string does not always works - probably it does work for those numbers too large (which is a nifty trick). – hakre Apr 29 '12 at 17:10