php遍历对象的方法

admin3年前PHP教程32

对于php来说,foreach是非常方便好用的一个语法,几乎对于每一个PHPer它都是日常接触最多的请求之一。那么对象是否能通过foreach来遍历呢?

答案是肯定的,但是有个条件,那就是对象的遍历只能获得它的公共属性。


// 普通遍历
class A
{
    public $a1 = '1';
    public $a2 = '2';
    public $a3 = '3';
 
    private $a4 = '4';
    protected $a5 = '5';
 
    public $a6 = '6';
 
    public function test()
    {
        echo 'test';
    }
}
$a = new A();
foreach ($a as $k => $v) {
    echo $k, '===', $v, PHP_EOL;
}
 
// a1===1
// a2===2
// a3===3
// a6===6

不管是方法还是受保护或者私有的变量,都无法遍历出来。只有公共的属性才能被遍历出来。其实,我们之前在讲设计模式时讲过的迭代器模式就是专门用来进行对象遍历的,而且PHP已经为我们准备好了相关的接口,我们只需要去实现这个接口就可以完成迭代器模式的创建了。具体的内容可以参考之前的设计模式系列文章:PHP设计模式之迭代器模式


// 实现迭代器接口
class B implements Iterator
{
    private $var = [];
 
    public function __construct($array)
    {
        if (is_array($array)) {
            $this->var = $array;
        }
    }
 
    public function rewind()
    {
        echo "rewinding\n";
        reset($this->var);
    }
 
    public function current()
    {
        $var = current($this->var);
        echo "current: $var\n";
        return $var;
    }
 
    public function key()
    {
        $var = key($this->var);
        echo "key: $var\n";
        return $var;
    }
 
    public function next()
    {
        $var = next($this->var);
        echo "next: $var\n";
        return $var;
    }
 
    public function valid()
    {
        $var = $this->current() !== false;
        echo "valid: {$var}\n";
        return $var;
    }
}
 
$b = new B([1, 2, 3, 4]);
 
foreach ($b as $k => $v) {
    echo $k, '===', $v, PHP_EOL;
}
 
// rewinding
// current: 1
// valid: 1
// current: 1
// key: 0
// 0===1
// next: 2
// current: 2
// valid: 1
// current: 2
// key: 1
// 1===2
// next: 3
// current: 3
// valid: 1
// current: 3
// key: 2
// 2===3
// next: 4
// current: 4
// valid: 1
// current: 4
// key: 3
// 3===4
// next:
// current:
// valid:

假如今天的文章只是讲之前讲过的迭代器模式,那就太没意思了,所以,咱们还要来学习一个更有意思的应用。那就是让对象可以像数组一样进行操作。这个其实也是使用PHP早已为我们准备好的一个接口:ArrayAccess。


// 让类可以像数组一样操作
class C implements ArrayAccess, IteratorAggregate
{
    private $container = [];
    public function __construct()
    {
        $this->container = [
            "one" => 1,
            "two" => 2,
            "three" => 3,
        ];
    }
    public function offsetSet($offset, $value)
    {
        if (is_null($offset)) {
            $this->container[] = $value;
        } else {
            $this->container[$offset] = $value;
        }
    }
    public function offsetExists($offset)
    {
        return isset($this->container[$offset]);
    }
    public function offsetUnset($offset)
    {
        unset($this->container[$offset]);
    }
    public function offsetGet($offset)
    {
        return isset($this->container[$offset]) ? $this->container[$offset] : null;
    }
 
    public function getIterator() {
        return new B($this->container);
    }
}
 
$c = new C();
var_dump($c);
 
$c['four'] = 4;
var_dump($c);
 
$c[] = 5;
$c[] = 6;
var_dump($c);
 
foreach($c as $k=>$v){
    echo $k, '===', $v, PHP_EOL;
}
 
// rewinding
// current: 1
// valid: 1
// current: 1
// key: one
// one===1
// next: 2
// current: 2
// valid: 1
// current: 2
// key: two
// two===2
// next: 3
// current: 3
// valid: 1
// current: 3
// key: three
// three===3
// next: 4
// current: 4
// valid: 1
// current: 4
// key: four
// four===4
// next: 5
// current: 5
// valid: 1
// current: 5
// key: 0
// 0===5
// next: 6
// current: 6
// valid: 1
// current: 6
// key: 1
// 1===6
// next:
// current:
// valid:

这个接口需要我们实现四个方法:

offsetSet($offset, $value),根据偏移量设置值offsetExists($offset),根据偏移量确定是否存在内容offsetUnset($offset),根据偏移量删除内容offsetGet($offset),根据依稀量获取内容

这里的偏移量就是我们常说的下标。通过实现这四个方法,我们就可以像操作数组一样的操作对象。当然,日常开发中我们可能并不会很经常的使用包括迭代器在内的这些对象遍历的能力。通常我们会直接去将对象转换成数组 (array) obj 来进行下一步的操作。不过,在java中,特别是JavaBean中会经常在类的内部有一个 List 为自己的对象来表示自身的集合状态。通过对比,我们发现PHP也完全可以实现这样的能力,而且使用迭代器和 ArrayAccess 接口还能够更方便的实现类似的能力。这是非常有用的一种知识扩展,或许下一个项目中你就能运用上这些能力哦!

测试代码: github/zhangyue050…

以上就是php遍历对象的方法的详细内容,更多关于php遍历对象的资料请关注其它相关文章!

免责声明:本文内容来自用户上传并发布,站点仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。请核实广告和内容真实性,谨慎使用。

相关文章

做站群买美国站群服务器租赁有几点问题是需要注意的

站群服务器最常见的就是香港站群服务器和美国站群服务器,这两种海外站群服务器的ip都比较多,最适合站群,大家可以优先考虑。但是做站群买美国站群服务器租赁有几点问题是需要注意的。安全性考察做网站运营的都知...

台湾服务器共享带宽还是独享带宽好用

台湾服务器共享带宽还是独享带宽好用?台湾服务器的带宽类型包括共享带宽和独享带宽。哪种更适合你取决于你的具体需求和预算。共享带宽是指多个用户共享同一个带宽资源,这意味着带宽可能会有一些限制,并且在高峰期...

高防服务器的优点以及区别?美国高防大带宽服务器租用选择哪家好?

什么是高防服务器高防服务器主要是指独立单个硬防防御50G以上的服务器,可以为单个客户提供安全维护,总体来看属于服务器的一种,根据各个IDC机房的环境不同,有的提供有硬防,有使用软防。简单来说,就是能够...

聊聊PHP中删除字符串的逗号和尾部斜杠的方法

正如标题所述,本文将给大家通过两个示例来介绍PHP删除字符串中的逗号以及尾部斜杠的方法,感兴趣的朋友咱们一起继续往下看吧~下面我们通过具体的实例分别讲解:第一个示例的要求则是“编写一个PH...

哪些企业需要租用新加坡大带宽服务器

哪些企业需要租用新加坡大带宽服务器?以下是一些需要租用新加坡大带宽服务器的企业或组织:大型网站:需要高速互联网连接、高带宽和高可用性,以提供更好的用户体验和更高的访问速度。网络游戏公司:需要高速互联网...

php中yum命令用法详解

在php中关于yum命令还是比较多的,主要是因为在配置linux环境,linux中安装、卸载等各种操作中,因此,掌握命令还是相当重要的,在很多命令中,最常见使用的就是yum命令,总共有七个yum命令,...