【问题标题】:Implement PHP interface such that object instance can be passed as array type argument?实现 PHP 接口,使对象实例可以作为数组类型参数传递?
【发布时间】:2009-06-03 11:37:27
【问题描述】:

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

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

function myFunction(array $argument){
}

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

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

【问题讨论】:

  • 为什么 ArrayObject 不起作用?
  • 我认为您要么必须更改类型提示,要么只需向函数提供数组。 array 是原始数据类型,不能被继承。
  • 数组不是对象,只要你必须使用数组 x 或 ArrayObject 来解决。

标签: php interface


【解决方案1】:

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

为什么不将函数签名更改为仅允许 ArrayObjects、ArrayIterators、ArrayAccesss、IteratorAggregates、Iterators 或 Traversables(取决于您的想在函数里面做什么)?

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

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

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

【讨论】:

    【解决方案2】:

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

    1. 删除 array 说明符,而是使用 is_array 和 instanceof ArrayObject 在函数内进行检查
    2. 在调用例程或作为上述 1. 的一部分时使用(数组)$ArrayObject。

    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',
     )
    

    【讨论】:

    • 请注意,第二个选项会将您的对象转换为将对象的成员名称映射到其值的数组,它不会让您使用 ArrayObject 函数!
    • 由于接口不是我定义的,我没有选择删除类型提示。我认为选项 2 最能满足我的目的,因为我希望对键和值有更多的控制权,而不是使用常规数组。所以当我将它传递给函数时,我将使用我自己的对象并将其转换为数组。
    • 注意 $a[]= 和 $a->append() 等价于 ArrayObject 实现数组访问。在某些时候 php.net 会记录他们的库。
    【解决方案3】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-29
      • 2016-04-22
      • 1970-01-01
      • 1970-01-01
      • 2013-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多