Dear list, I recently ran into big problems with crc32() and ip2long() both of which I was using in the same codebase.
I know these issues have been debated at length in the past, but this really needs to be fixed. Anytime you persist these values (to any external medium, files or databases) you're sitting on a time bomb. I realize some of you have countless technical arguments why these functions "work as they're supposed to", but php is a high-level language, and these functions do not work consistently across platforms. It can't be the developer's responsibility to write unit-tests for return-values on internal functions - nor should we need to write elaborate wrapper-functions for these functions to get them to work consistently. There are dozens (if not nearing 100) different user-land solutions to this problem, so it's not like the need isn't there - anyone who has ever used these functions probably needed a work-around. The need for an enormous red WARNING label, and elaborate explanation on the crc32() documentation page says it all - nothing this simple, that has been standardized for this long, should require an elaborate explanation, complicated work-arounds or for that matter a lot of thought on the developer's side. Since a signed 32-bit integer value is the lowest common denominator, that's what the functions ought to return, so that at least the return value is consistent across platforms, and you can decide (for example) whether to persist it to a signed or unsigned INT in a database, and except it to work the same everywhere. (Databases at large, and at least MySQL, correctly persists either signer or unsigned INT values across platforms.) The simplest work-around I have been able to come up with so far, is this: var_dump(unpack('l', pack('l', ip2long('255.255.255.0')))); var_dump(unpack('l', pack('l', crc32('123456789_00_0')))); Forcing the value into smaller (on some platforms) 32-bit integer, and then unpacking it, provides a consistent value on 32-bit and 64-bit systems, and on Windows. Of course there is backwards compatibility to consider for this broken behavior, so I propose the simplest solutions is to just add a new pair of replacement functions. You don't need to deprecate the existing functions, because they work as prescribed, however useless they may be for any practical applications. The new functions and backwards compatible implementations for older versions of php might look like this: /** * @param string * @return int a signed (32-bit) integer value */ function ip2int($ip_string) { return unpack('l', pack('l', ip2long($ip_string))); } /** * @param int a signed integer value * @return string */ function int2ip($ip_int) { return long2ip($ip_int); } /** * @param string * @return int a signed integer value */ function crc32i($string) { return unpack('l', pack('l', crc32($string))); } int2ip() would just be an alias for long2ip(). I spent almost a full day fighting with these functions and testing work-arounds, and I bet every php developer who encounters a need for one of these functions will some day sooner or later go through the same. Userland solutions are not solutions to fundamental problems that affect everyone who uses the functions. Arguing that this behavior is "correct" by some technical definition, is futile - the behavior is problematic for practical reasons, so technical circumstances don't really matter here. Core functions need to actually work consistently and predictably for as many users as possible - optimizing for C developers and people with deep technical knowledge of operating system and compiler specifics does not make sense for a language like php. Please look for reasons to agree rather than disagree out of spite. As said, I know this has been debated at length in the past, and always with the same outcome - but the simple fact is that these functions don't work for the end-users, and they do not provide proper cross-platform support. No one cares how integers work internally, in C, in the CPU, or in the VM, and it's not relevant. There is no need to put anyone through all this unnecessary hardship. These functions need to work **for php developers**. - Rasmus Schultz