[字号:  ]

关于一道笔试题——明白看手册有多重要

发布时间:2008-10-31 16:40   作者: laruence   信息来源: PHPChina 开源社区门户
· 作者:laruence(http://www.laruence.com/)
· 本文地址: http://www.laruence.com/2008/10/31/574.html
· 转载请注明出处

中午的时候,收到一封求教信,是关于这样的一道面试题:

使对象可以像数组一样进行foreach循环,要求属性必须是私有。


刚接触到题的时候,我也没有考虑到Iterator模式,试了几个一般想法,失败以后。。。。就直接去翻看了foreach的源码实现,期望发现foreach处理对象的时候是否有什么特殊性,可以做为突破口。

跟踪了半天以后发现了核心逻辑中的一个奇怪的switch:

从这个结构,我们可以看到,对象分为ZEND_ITER_OBJECT和ZEND_ITER_PLAIN_OBJECT, 这是什么意思呢?

这就要讲到PHP的内置接口Iterator了,PHP5开始支持了接口, 并且内置了Iterator接口, 所以如果你定义了一个类,并实现了Iterator接口,那么你的这个类对象就是ZEND_ITER_OBJECT,否则就是ZEND_ITER_PLAIN_OBJECT.

对于ZEND_ITER_PLAIN_OBJECT的类,foreach会通过HASH_OF获取该对象的默认属性数组,然后对该数组进行foreach.
而对于ZEND_ITER_OBJECT的类对象,则会通过调用对象实现的Iterator接口相关函数来进行foreach, 所以, 对于这道笔试题, 可以作出如下的答案:

以上代码在我的php 5.3下运行正常。

后记: 看手册是很重要的,,,,,, 别人一眼就看出来了,我却绕了这么大的弯子

[ 本帖最后由 laruence 于 2008-11-24 23:15 编辑 ]

最新回复

lxccai at 2008-10-31 16:54:56
连源代码都翻出来~~好像手册中有看到过~
laruence at 2008-10-31 17:01:22
恩,恩,,,,
我比较老土,走了弯路, 以后还是要多看手册,呵呵

唉,丢~~~~~~
NoAngels at 2008-10-31 17:13:40
难道牛人也不看SPL的吗?
laruence at 2008-10-31 17:14:52

QUOTE:

原帖由 NoAngels 于 2008-10-31 17:13 发表
难道牛人也不看SPL的吗?
呵呵,要看,要看,只是之前没有应用需要用
以后就会看了。。
mrhhsg at 2008-10-31 17:22:50
我更想知道楼主为什么对这个题不敢恭维?
laruence at 2008-10-31 17:43:18
不知道他想考察什么,SPL虽说看起来很强大。
但是,实际运用的时候,有点偏了。
Altair at 2008-11-01 20:21:27
SPL是PHP5中新增的一个很重要的内容。出题的人想考的应该就是SPL的简单应用。
xiaojie515 at 2008-11-01 20:25:38
刚在你的blog里看过这篇文章了..
xiaojie515 at 2008-11-01 20:26:54
laruence,帮忙看下我的问题吧
扩展php时出错了...
http://bbs.phpchina.com/thread-87769-1-1.html
sunceenjoy at 2008-11-03 11:24:43
可见对php的研究之深入啊。但我怎么在手册里找不到这快内容
Hellex at 2008-11-03 12:08:27
PHP5可以遍历对象了
Sunyanzi at 2008-11-03 18:53:05

QUOTE:

6.使对象可以像数组一样进行foreach循环,要求属性必须是私有。
(Iterator模式的PHP5实现,写一类实现Iterator接口)
原面试题就是这样的嘛 ... 提示可以用 Iterator 了~~
七月十五 at 2008-11-08 11:35:47
建家兄对SPL有深刻的领悟