PHP class 常量似乎总是被解释为字符串
PHP class constants seems to always be interpreted as strings
A class 常量似乎总是被解释为字符串,尽管它被定义为整数。为什么 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)
-cast 更好的方法来做到这一点?
我不太确定你的期望是什么,但请注意 !==
的 precedence 比 &
高,所以你在 1
和true
.
你的意思是:
if( ($flags & self::ALL) !== $flags )
对不起,是我的错,我走错了方向。解决方案是
if( ( $flags & self::ALL ) !== $flags )
添加括号。 !==
运算符似乎比 &
.
具有更高的优先级
没有括号,首先将代码段 self::ALL !== $flags
计算为 FALSE
,然后对 $flags & FALSE
进行计算。
PHP 是……:-(
A class 常量似乎总是被解释为字符串,尽管它被定义为整数。为什么 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)
-cast 更好的方法来做到这一点?
我不太确定你的期望是什么,但请注意 !==
的 precedence 比 &
高,所以你在 1
和true
.
你的意思是:
if( ($flags & self::ALL) !== $flags )
对不起,是我的错,我走错了方向。解决方案是
if( ( $flags & self::ALL ) !== $flags )
添加括号。 !==
运算符似乎比 &
.
没有括号,首先将代码段 self::ALL !== $flags
计算为 FALSE
,然后对 $flags & FALSE
进行计算。
PHP 是……:-(