我有一个函数,我想使变量长度,最后一项可选地是类常量的位掩码。但是,我无法想出一种方法来检查最后一项是否是位掩码而不是其他东西,因为它应该是可选的。
class D {
const A = 1;
const B = 2;
const C = 4;
const D = 8;
public function test(){
$args = func_get_args();
$possibly_flags = $args[count($args)-1];
if(???){ // do some test here to find out
// do stuff with the flags check
}
}
}
$d->test($val1, $val2, [...,], D::A|D::B);
有什么方法可以解决这个问题吗?
答案 0 :(得分:1)
结束使用不同的类来保存标志和其他任何设置,然后测试它是否是该类的实例。由于该类仅用于此目的,因此它的效果相当不错。我现在使用的例子如下:
class D {
const A = 1;
const B = 2;
const C = 4;
const D = 8;
public function test(){
$args = func_get_args();
$possibly_flags = $args[count($args)-1];
if($possibly_flags instanceof Settings){
// do stuff with the flags
}
}
}
class Settings(){
public $flags;
public function __construct($flags){
$this->flags = $flags;
}
}
$d->test($val1, $val2, [...,], new Settings(D::A|D::B));
答案 1 :(得分:0)
我建议更透明的课程设计:
class D {
const A = 1;
const B = 2;
public function setBitmask($bitmask) {
$this->bitmask = $bitmask;
return $this;
}
public function test() {
$args = func_get_args();
if ($this->bitmask /* whatever */) {
/* whatever else */
}
}
protected $bitmask = self::A | self::B;
}
您可以调用(new D())->setBitmask(D::A)->test($x, $y);
如果你坚持参数给定 - 可变长度函数和可选的最后一个参数 - 那么你将需要使用一个标记来区分这两个参数。例如,如果null是您的哨兵:
(new D())->test($val1, $val2, null, D::A)
然后在你的方法中:
public function test() {
$args = func_get_args();
if (null === $args[count($args)-2]) {
$bitmask = $args[count($args)-1];
/* here you would check that bitmask is possible */
} else {
$bitmask = D::A; /* default if you want it */
}
if ($bitmask /* whatever */) {
/* whatever else */
}
}
这变得非常讨厌和脆弱,所以一定要考虑我上面描述的访问方法或@ Jack的两个参数的方法。
答案 2 :(得分:0)
您传递了两种不同的数据,因此在函数声明中需要两个不同的参数:
public function test(array $args, $flags = 0)
{
}
...
$d->test([$var1, $var2, $var3], D::A);
这可以避免论证的含糊不清。