测试可变长度参数函数的按位标志

时间:2014-03-28 02:14:05

标签: php bit-manipulation

我有一个函数,我想使变量长度,最后一项可选地是类常量的位掩码。但是,我无法想出一种方法来检查最后一项是否是位掩码而不是其他东西,因为它应该是可选的。

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

有什么方法可以解决这个问题吗?

3 个答案:

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

这可以避免论证的含糊不清。