Jul
12
2007

PHP Array Index Implicit Casts and uniqid()

In addition to performing implicit string-to-number casts for arithmetic expressions, PHP implicitly casts array keys in the same manner. Thus, even if one puts an integer in quotes as an array key, PHP will convert it back to an integer. However (as we learn from the response to Bug 21954) explicitly casting the index to a string works.

So even though PHP claims to offer associative and indexed arrays, the implicit casting will be busily converting associative keys to index keys behind the curtain. Things get particularly ugly with integers g.t. 2^32 (above bug report plus Bug 34419). And notice the snippy resolution comment: “This hasn’t changed, will not change, and is not a bug.” So large integers that start off as strings are cast to integers, but being too large, are then converted to floats. That’s intuitive.

I was storing objects in an associative array, using the objects’ id as the keys and I was generating the ids with uniqid(). Uniqid generates 13 character strings that appear to be hexadecimal values cast to a string. Most of these values will have an [a-f] character, but occasionally they contain only digits. In this unfortunate case, these are cast to long integers then cast again to a float. Except that I serialized one such array and saw a negative integer listed as the array key! Whatever the exact mechanism, after unserialization I was unable to retrieve one object from an array, even using array_keys().

This is a PHP language design flaw, in my opinion. The default unique-id generator generates values that randomly map into two disjoint sets of array keys: associative string keys or numeric index keys. Given the schizophrenic array index casts, one would certainly expect uniqid() to uniformly generate strings or integers. So at a cost of about 12 hours, I now know to use the optional prefix argument all the time.

Such problems are avoided in Perl because arrays are declared to be associative or numeric, so keys aren’t being cast behind one’s back. PHP is younger than Perl, which I judge to be largely free from these types of asymmetries. And I didn’t look through all of the remaining PHP bug reports after finding the info I needed: since two years have elapsed, maybe PHP has improved this by now.

posted in php by Bozzie

2 Comments to "PHP Array Index Implicit Casts and uniqid()"

  1. Rolf wrote:

    Excellent article, thanks for avoiding me to deal with another PHP design flaw.
    If someone knows if PHP improved on this point, it would be cool to leave a small comment! 🙂

  2. Hari Karam wrote:

    Nope not yet…

    Is there a way to programmatically override this feature?

 
Powered by Wordpress and MySQL. Theme by openark.org