PHP 如何迭代一个对象 ( 上 )

你有没有想过,或者试验过,使用 foreach 迭代一个对象会输出什么?

你有没有想过,或者试验过,使用 foreach 在对象内部迭代 $this 会输出什么 ?

你有没有想过,或者试验过,在子类对象内部使用 foreach 迭代 $this 会输出什么 ?

如果你没有想过,没关系的,现在想也还来得及。

如果你没有试验过,那么,我们就一起试验一下吧。

PHP 对象迭代

总所周知,相较于远古的 PHP 4 ,面向对象是 PHP 5 新增的最大的功能。也从那时起,我们就可以使用 foreach 来迭代一个对象。

另一个总所周知的是,面向对象有三大特性: 封装、继承、多态。那么,foreach 迭代一个对象碰上了封装、继承、多态,它们会产生什么样的化学效应呢 ?

我们就不卖关子了,PHP 迭代一个对象,有几个重要的原则:

  1. 只会迭代属性不迭代方法。
  2. 只会迭代当前作用域范围内的属性。

只迭代属性不迭代方法

PHP 中使用 foreach 迭代一个对象,只会迭代该对象的属性,而不会迭代它的方法,无论是静态方法还是实例方法,无论是公开方法还是私有方法。

例如下面这段代码,我们定义了两个属性和一个静态方法还有一个实例方法,而输出,只会看到属性。

<?php 

class Person
{
    var $name;
    var $age;

    public function __construct($name,$age)
    {
        $this->name = $name;
        $this->age  = $age;
    }


    public static function walk() {
        return "I'm walking";
    }


    public function eat()
    {
        return "I'm eating";
    }
}


$me = new Person("语飞",30);

foreach($me as $k => $v )
{
    echo $k, " => ", $v, "\n";
}

运行这段代码,输出结果如下

[yufei@www.twle.cn helloworld]$ php d.php
name => 语飞
age => 30

只会迭代当前作用域范围内的属性

「 只会迭代当前作用域范围内的属性 」是相对 「 可见性 」( public 、protected 、private )而言的:

  1. 在对象的实例方法内部迭代 $this 会输出该对象的所有自定义属性,加上继承而来的所有 public 和 protected 属性。
  2. 在对象的外部迭代对象会输出该对象的所有 public 属性,包括继承而来的公开属性。

实例方法中迭代 $this 会输出该对象的所有自定义属性

我们修改下上面的实例,添加一个 protected 属性和一个 private 属性

<?php 

class Person
{
    public $name = "语飞";
    public $sexy  = "男";

    protected $age = 30;

    private $married = "no";

    public function intro()
    {
        foreach($this as $k => $v )
        {
            echo $k, " => ", $v, "\n";
        }       
    }
}


$me = new Person();
$me->intro();

运行这段代码,输出结果如下

[yufei@www.twle.cn helloworld]$ php d.php
name => 语飞
sexy => 男
age => 30
married => no

在对象的外部迭代对象会输出该对象的所有 public 属性

在对象的外部使用 foreach 迭代对象会输出该对象的所有 public 属性

<?php 
class Person
{
    public $name = "语飞";
    public $sexy  = "男";

    protected $age = 30;

    private $married = "no";
}


$me = new Person();
foreach($me as $k => $v )
{
    echo $k, " => ", $v, "\n";
}

运行以上范例,输出结果如下

[yufei@www.twle.cn helloworld]$ php d.php
name => 语飞
sexy => 男

在子类对象内部迭代对象

在子类对象内部迭代会输出该对象的所有属性和继承而来的所有 public 和 protected 属性

<?php 

class Person
{
    public $name = "语飞";
    public $sexy  = "男";

    protected $age = 30;

    private $married = "no";
}

class Employee extends Person {
    public $job = "CEO";

    public function intro()
    {
        foreach($this as $k => $v )
        {
            echo $k, " => ", $v, "\n";
        }       
    }
}


$me = new Employee();
$me->intro();

输出结果如下

[yufei@www.twle.cn helloworld]$ php d.php
job => CEO
name => 语飞
sexy => 男
age => 30

从结果中可以看到,父类的私有属性 $married 并没有输出。也就不会参与迭代

在外部迭代一个子类对象

在外部迭代一个子类对象输出该对象的所有 public 属性和继承而来的所有 public 属性

<?php 

class Person
{
    public $name = "语飞";
    public $sexy  = "男";

    protected $age = 30;

    private $married = "no";
}

class Employee extends Person {
    public $job = "CEO";
}


$me = new Employee();
foreach($me as $k => $v )
{
    echo $k, " => ", $v, "\n";
}

输出结果如下

[yufei@www.twle.cn helloworld]$ php d.php
job => CEO
name => 语飞
sexy => 男

结束语

综上所述,PHP 迭代一个对象的规则可以归纳为

使用 foreach 迭代一个对象只会输出当前作用域可见的对象的属性。

关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.