实现PHP接口,使对象实例可以作为数组类型参数传递?

时间:2009-06-03 11:37:28

标签: php interface

在PHP中,可以指定参数类型,尽管它们称之为类型提示。

我正在实现一个接口,其中一个函数指定一个数组作为参数类型:

function myFunction(array $argument){
}

我想定义一个类,其实例可以用作此函数的参数。换句话说,它会扩展ArrayObject或实现ArrayAccess或其他东西。

是否有适用于此的内置接口或抽象类? (ArrayObject没有)

3 个答案:

答案 0 :(得分:3)

这是不可能的。 array()不是任何类的对象。因此,它无法实现任何 界面(见here)。所以你不能互换地使用对象和数组。解决方案很大程度上取决于您希望实现的目标。

为什么不将功能签名更改为仅允许ArrayObject s,ArrayIterator s,ArrayAccess s,IteratorAggregate s,Iterator s或Traversable s(取决于您在函数内部要做的事情)?

如果必须依赖传递对象的interation-capabilities,则应使用Traversable作为类型提示。这将确保该对象可以与foreach()一起使用。如果您需要对对象进行类似数组的键访问(例如$test['test']),则应使用ArrayAccess作为类型提示。但是,如果您需要传递的对象具有特定的自定义类型,请使用自定义类型作为类型提示。

另一种选择是根本不使用类型提示并确定函数体内传递的参数的类型并相应地处理参数(或抛出InvalidArgumentException或类似的东西)。

if (is_array($arg)) { ... }
else if ($arg instanceof Traversable) { ... }
else if ($arg instanceof ArrayAccess) { ... }
else {
    throw new InvalidArgumentException('...');
}

答案 1 :(得分:2)

没有,但我建议两种选择:

  1. 删除数组说明符,而不是使用is_array和instanceof ArrayObject在函数内检查
  2. 在调用例程或上面的1.的一部分时使用(array)$ ArrayObject。
  3. soulmerge 的示例: - )

    function myFunction(array $argument){
        echo var_export($argument,true);
    }
    $a = new ArrayObject();
    $a[] = 'hello';
    $a[] = 'and goodbye';
    
    myFunction((array)$a);  
    

    输出

     array (
       0 => 'hello',
       1 => 'and goodbye',
     )
    

答案 2 :(得分:0)

不,这是不可能的,因为数组是PHP中的基本类型。类的实例是一个对象,此时PHP内部比较已停止(未检查接口等)。

您可以从对象中创建一个数组:

$array = array();
foreach ($yourObject as $key => $value) {
    $array[$key] = $value;
}