user2690527
user2690527

Reputation: 1881

PHP class constants seems to always be interpreted as strings

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?

Upvotes: 0

Views: 79

Answers (2)

jeroen
jeroen

Reputation: 91742

I am not exactly sure what you expect, but note that !== has a higher precedence than & so you are doing a bitwise AND between 1 and true.

Do you perhaps mean:

if( ($flags & self::ALL) !== $flags )

Upvotes: 3

user2690527
user2690527

Reputation: 1881

Sorry, it was my fault and I went into the wrong direction. The solution is

if( ( $flags & self::ALL ) !== $flags )

to add parentheses. The !== operator seems to have a higher priority than &.

Without the parantheses, first the snippet self::ALL !== $flags is evaluated to FALSE and then $flags & FALSE is evaluated.

PHP is ... :-(

Upvotes: 1

Related Questions