Home  >  Article  >  Backend Development  >  How to detect whether a class can be traversed by foreach in PHP

How to detect whether a class can be traversed by foreach in PHP

醉折花枝作酒筹
醉折花枝作酒筹forward
2021-06-10 17:15:531619browse

This article will introduce to you how to detect whether a class can be traversed by foreach in PHP. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to everyone.

How to detect whether a class can be traversed by foreach in PHP

In PHP, we can easily determine the type of a variable, and we can also easily determine the length of an array to determine whether the array can be traversed. What about classes? How do we know whether this class can be traversed through foreach? In fact, PHP already provides us with a ready-made interface.

class Obj1
{
    public $v = 'V:Obj1';
    private $prv = 'prv:Obj1';
}

$obj1 = new Obj1();
echo $obj1 instanceof Traversable ? 'yes' : 'no', PHP_EOL; // no

class Obj2 implements IteratorAggregate
{
    public $v = 'V:Obj2';
    private $prv = 'prv:Obj2';
    public function getIterator()
    {
        return new ArrayIterator([
            'v' => $this->v,
            'prv' => $this->prv,
        ]);
    }
}

$obj2 = new Obj2();
echo $obj2 instanceof Traversable ? 'yes' : 'no', PHP_EOL; // yes

As can be seen from the above example, each \$obj1 cannot be judged by Traversable, so it cannot be traversed. The second $obj2 implements the iterator interface, and this object can be judged through Traversable. In the PHP manual, the Traversable interface is the interface used to detect whether a class can be traversed by foreach.

This interface has several features:

  1. Built-in classes that implement this interface can use foreach to traverse without implementing the IteratorAggregate or Iterator interface.

  2. This is an internal engine interface that cannot be implemented in PHP scripts. The IteratorAggregate or Iterator interface can be used instead.

That is to say, this interface does not require us to implement it manually. We only need our class to implement the iterator-related interface to pass the verification judgment of this interface. If we implement this interface alone, an error will be reported and we will be prompted to implement the IteratorAggregate or Iterator interface.

// Fatal error: Class ImplTraversable must implement interface Traversable as part of either Iterator or IteratorAggregate in Unknown 
class ImplTraversable implements Traversable{

}

In fact, in the previous article, we have verified that the object can be traversed, and it can be traversed by foreach without implementing any iterator interface. It prints all public properties.

// foreach
foreach ($obj1 as $o1) {
    echo $o1, PHP_EOL;
}

foreach ($obj2 as $o2) {
    echo $o2, PHP_EOL;
}

// V:Obj1
// V:Obj2
// prv:Obj2

That is to say, the role of this Traversable interface is not obvious in actual use. I believe that most of us have never used this interface to determine whether a class can be traversed.

But from the above example, we can see that iterators can customize the content we need to output. Relatively speaking, it is more flexible and controllable than direct object traversal. In addition, the Traversable interface cannot make a judgment if the array is forced to an object.

$arr = [1, 2, 3, 4];
$obj3 = (object) $arr;
echo $obj3 instanceof Traversable ? 'yes' : 'no', PHP_EOL; // no

foreach ($obj3 as $o3) {
    echo $o3, PHP_EOL;
}

In fact, the array itself is a natural iterable object. Although type coercion is performed here, it is actually more appropriate to regard the object of array coercion as an object that implements an iterator by default. Of course, the greater significance of this type of interface lies in code specifications and mandatory inspections.

Test code:

https://github.com/zhangyue0503/dev-blog/blob/master/php/202003/source/%E5%9C%A8PHP%E4%B8%AD%E6%A3%80%E6%B5%8B%E4%B8%80%E4%B8%AA%E7%B1%BB%E6%98%AF%E5%90%A6%E5%8F%AF%E4%BB%A5%E8%A2%ABforeach%E9%81%8D%E5%8E%86.php

Recommended learning: php video tutorial

The above is the detailed content of How to detect whether a class can be traversed by foreach in PHP. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:segmentfault.com. If there is any infringement, please contact admin@php.cn delete