1

在 PHP 中,我希望能够遍历一组类以帮助设置、插入和验证值。在方法 args 中使用类作为类型将使代码更加严格,这将有助于避免错误。

我能够访问该集合,但只能通过公共数组或方法($values->array$values->get())。我希望能够$values直接用于更简洁的代码。例如,要访问引用,我需要使用$values->array[0]or$values->get()[0]而不是$values[0]. 如何用 PHP 实现这一点?

预期用途:

$values = new Values(
    new Value('foo', 'bar'),
    new Value('foo2', 'bar2'),
);

function handleValues(Values $exampleValues): void
{
    foreach ($exampleValues as $exampleValue) {
        //do something with $exampleValue->field, $exampleValue->value
    }
}

handleValues($values);

课程:

class Values
{
    public array $array;

    public function __construct(Value... $value){
        $this->array = $value;
    }
}

class Value
{
    public string $field;
    public mixed $value;

    public function __construct(string $field, mixed $value)
    {
        $this->field = $field;
        $this->value = $value;
    }
}
4

1 回答 1

0

听起来你真正想要的是一个类型化数组,但 PHP 中没有这样的东西。

许多静态分析工具和 IDE支持记录类型化数组,使用“PHPDoc 语法”,如下所示:

/** @param Value[] $values */
function foo(array $values) {}

如果你想要一个可以循环的对象,最简单foreach方法是实现接口,并使用它将内部数组包装在一个对象中:IteratorAggregateArrayIterator

class Values implements IteratorAggregate
{
    private array $array;

    public function __construct(Value... $value){
        $this->array = $value;
    }
    
    public function getIterator(): Iterator {
        return new ArrayIterator($this->array);
    }
}

$values = new Values(
    new Value('foo', 'bar'),
    new Value('foo2', 'bar2'),
);

foreach ( $values as $value ) {
    var_dump($value);
}

如果您想要一个可以通过[...]语法引用的对象,请实现ArrayAccess接口。有四种方法,但是对于这种情况,每种方法都可以轻松实现,并且手册中有一个示例。


还有一个内置ArrayObject实现了这两个接口(以及更多接口),您可以对其进行扩展以一次性获得许多类似数组的行为。


另一方面,如果您只想验证数组是否仅包含特定类型,那么就这样做。单行版本将是:

$valid = array_reduce($values, fn($valid, $next) => $valid && $next instanceof Value, true);

或者对于大型数组的稍微更有效的版本(因为它在找到无效项时会完全停止循环):

$valid = true;
foreach ( $values as $next ) {
    if ( ! $next instanceof Value ) {
         $valid = false;
         break;
    }
}
于 2022-02-22T19:54:28.730 回答