Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I define PHP_INT_SIZE to 4 bytes on 64-bit system running PHP?

Tags:

php

int

I am using PHP 5.3.

On my 32-bit system the size of an INT:

print "PHP_INT_MAX: " . PHP_INT_MAX . "\n";
print "PHP_INT_SIZE: " . PHP_INT_SIZE . " bytes (" . (PHP_INT_SIZE * 8) . " bits)\n";
  • PHP_INT_MAX: 2147483647
  • PHP_INT_SIZE: 4 bytes (32 bits)

However, part of an an encoding algorithm I am using relies on the fact that an int is the above size (4 bytes). When I run the code on my web host's server, it is a 64-bit system and the int size is twice as large.

Is there a way to force "(int)" cast to use the 32-bit size?

For example, assume the following code:

$test = 4170266799;
print $test;                     
print (int) $test;

On my 32-bit system, the output is:

4170266799
-124700497

On my 64-bit system, the output is:

4170266799
4170266799

Is it possible to force the value of an INT to be 4 bytes, even when the architecture changes from 32-bit to 64-bit?

like image 249
Mick Avatar asked Nov 14 '11 21:11

Mick


2 Answers

No, this is very much dependant upon the platform itself:

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.

And because the values that expose the integer size and integer maximum are constants, they can't be changed - being determined at compile-time of PHP based on the current system.

Not much consolation, but this is why relying on something such as a constant (that isn't yours to change, and is subject to change per build), or any kind of "sizeof` implementations are just as evil as magic numbers in code - don't do it. One thing that we can be sure of (at least, I hope!) is that 4 is and always will be 4, but not that x, y, or z will represent 4, even if they do now.

like image 86
Grant Thomas Avatar answered Oct 04 '22 03:10

Grant Thomas


Referencing this question on Stack Overflow, I have found a solution that seems to work in my early tests:

function thirtyTwoBitIntval($value)
{                  
    if ($value < -2147483648)
    {
    return -(-($value) & 0xFFFFFFFF);
    }
    elseif ($value > 2147483647)
    {
        return ($value & 0xFFFFFFFF);
    }
    return $value;
}


$test = 4170266799;
print $test;                     
print (int) $test;
print thirtyTwoBitIntval($test);

And the output on the 32-bit system is:

4170266799  # $test = 4170266799
-124700497  # (int) $test
-124700497  # thirtyTwoBitIntval($test);

And the output on the 64-bit system is:

4170266799  # $test = 4170266799
4170266799  # (int) $test
-124700497  # thirtyTwoBitIntval($test);
like image 40
Mick Avatar answered Oct 04 '22 04:10

Mick