A class constant always seems to be interpreted as a string although it is defined as an integer. Why does PHP do this kind of type juggling and how do I prevent it?
See the following code:
class BitSet {
const NONE = 0;
const FOO = 1;
const BAR = 2;
const ALL = 3;
public function __construct( $flags = self::NONE ) {
if( $flags & self::ALL !== $flags )
throw new \OutOfRangeException( '$flags = '.$flags.' is out of range' );
$this->value = $flags;
}
protected $value = self::NONE;
}
$bs = new BitSet( BitSet::FOO );
The last line (the invocation of the constructor) throws the OutOfRangeException
:
PHP Fatal error: Uncaught exception 'OutOfRangeException' with message '$flags = 1 is out of range' in test-case.php:12
Stack trace:
#0 /srv/www/matthiasn/class-constant-debug.php(19): BitSet->__construct('1')
#1 {main}
thrown in /srv/www/matthiasn/class-constant-debug.php on line 12
As you can clearly see from backtrace entry #0 the constant BitSet::FOO
is passed as a character not as an integer. Hence, the bit mask operation $flags & self::ALL !== $flags
is not performed on integers but on the bitwise ASCII representation and therefore fails.
What the hell?! Is there any better way to get this right than to do an explicit (int)
-cast everywhere?