PHP类常量似乎总是被解释为字符串

时间:2015-05-16 13:40:48

标签: php type-conversion class-constants

类常量似乎总是被解释为字符串,尽管它被定义为整数。为什么PHP会做这种类型的杂耍,我该如何预防呢?

请参阅以下代码:

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 );

最后一行(构造函数的调用)抛出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

从回溯条目#0可以清楚地看到,常量BitSet::FOO作为字符而不是整数传递。因此,位掩码操作$flags & self::ALL !== $flags不是对整数执行,而是按位ASCII表示,因此失败。

到底是什么?!有没有更好的方法来做到这一点,而不是做一个明确的(int) - 到处播放?

2 个答案:

答案 0 :(得分:3)

我不确定您的期望,但请注意!==的{​​{3}}高于&,因此您在1和{{{{}}之间进行按位AND 1}}。

你或许是指:

true

答案 1 :(得分:1)

对不起,这是我的错,我走向了错误的方向。解决方案是

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

添加括号。 !==运算符的优先级似乎高于&

如果没有parantheses,首先会将代码段self::ALL !== $flags评估为FALSE,然后评估$flags & FALSE

PHP是...: - (