PHP 如何迭代一个对象 ( 上 )
你有没有想过,或者试验过,使用 foreach
迭代一个对象会输出什么?
你有没有想过,或者试验过,使用 foreach 在对象内部迭代 $this
会输出什么 ?
你有没有想过,或者试验过,在子类对象内部使用 foreach 迭代 $this
会输出什么 ?
如果你没有想过,没关系的,现在想也还来得及。
如果你没有试验过,那么,我们就一起试验一下吧。
PHP 对象迭代
总所周知,相较于远古的 PHP 4 ,面向对象是 PHP 5 新增的最大的功能。也从那时起,我们就可以使用 foreach 来迭代一个对象。
另一个总所周知的是,面向对象有三大特性: 封装、继承、多态。那么,foreach 迭代一个对象碰上了封装、继承、多态,它们会产生什么样的化学效应呢 ?
我们就不卖关子了,PHP 迭代一个对象,有几个重要的原则:
- 只会迭代属性不迭代方法。
- 只会迭代当前作用域范围内的属性。
只迭代属性不迭代方法
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 )而言的:
- 在对象的实例方法内部迭代
$this
会输出该对象的所有自定义属性,加上继承而来的所有 public 和 protected 属性。 - 在对象的外部迭代对象会输出该对象的所有
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 迭代一个对象只会输出当前作用域可见的对象的属性。