一道关于PHP的代码题

我们公司招聘PHP开发人员的时候,电话面试之前会有一个笔试。也就是说,给应聘者几道PHP语言和MySQL数据库开发方面相关的问题,再给他一个晚上的时间来回答这些问题;第二天早上之前应聘者需将答案通过电子邮件发回来,随后公司的核心开发人员会根据其回答问题的情况来决定是否需要进行下一阶段的面试(电话面试或当面面试)。

设计比较好一点的技术方面的问题是比较困难的,因此公司常常也会让新来的开发人员设计几道问题以供参考。

2007年12月4日(周二),我在编写程序生成两份数据报告的时候,根据程序调试过程中出现的问题总结了如下一道问题。这个问题着重考察对PHP中变量引用(variable reference,相当于C里面的指针)、数组遍历这两方面的掌握,需要对相关知识有清晰的理解才能回答准确。这类问题并不一定适合在面试的时候用,不过,用这个问题来温习一下PHP中的一些技术要点还是有些意思的,因此我一直把这个问题收录着。

<?php
$data = array('a', 'b', 'c');

foreach ($data as $key => $val) {
    $val = &$data[$key];
}
?>


问题1: 程序执行时,每一次循环结束后变量$data的值是什么?请解释。
问题2: 程序执行完以后,变量$data的值是什么?请解释。

补充说明:本文草稿完成于2008-10-21。
标签: 
类别: 

评论

关注一下,为什么呢

我的猜测,$val是在$data外面临时开辟的内存空间。

循环0: array(a, b, c) $val 引用 $data[0] = a 的地址;

循环1: array(b, b, c) $val = b, 由于$val 引用了$data[0]的地址,所以,$data[0] = b,同时 $val 引用 $data[1] = b 的地址;

循环2: array(b, c, c) 原理同循环1;

执行程序验证了我的结果,但不知道我的解释是否正确,望不吝赐教。:)

blueManta说得很对。

举例说明变量引用(reference):
$a = NULL; // 释放变量所占用的内存空间(如果该变量已经存在的话)
$a = $b; // $a复制了变量$b的值。这个赋值导致变量$a创建并指向一个新的内存空间($a指向该内存空间所在地址);$a和$b指向不同的内存空间(指向不同的内存空间地址)。对$a的操作不影响$b(除非$b是个对象)。
$a = &$b; // $a成为一个引用(引用类型的变量),直接指向变量$b。$a和$b指向相同的内存空间。通常情况下,对$a的操作等同于对$b进行操作。

文中所述数组$data的完整表达形式如下:
$data = array(
0 => 'a', // 内存空间A
1 => 'b', // 内存空间B
2 => 'c', // 内存空间C
);

循环过程:
$key = 0; $val = 'a'; // $val复制了变量$data[0]的值。这个赋值导致变量$val创建并指向一个新的内存空间X;$val和$data[0]指向不同的内存空间。
$val = &$data[0]; // $val成为一个引用,直接指向变量$data[0](原始数组第一个单元)。$val和$data[0]指向相同的内存空间A。
$key = 1; $val = 'b'; // 赋值操作导致$val所指向的内存空间的值被改变了;$data[0]指向相同的内存空间,所以$data[0]的值也改变了。
$val = &$data[1]; // $val还是一个引用,不过现在指向变量$data[1](原始数组第二个单元)。$val和$data[1]指向相同的内存空间B。
$key = 2; $val = 'c'; // 赋值操作导致$val所指向的内存空间的值被改变了;$data[1]指向相同的内存空间,所以$data[1]的值也改变了。
$val = &$data[2]; // $val还是一个引用,不过现在指向变量$data[2](原始数组第三个单元)。$val和$data[2]指向相同的内存空间C。

可参考PHP.net网站关于array、foreach和reference三个章节中的相关说明。

Thank you,学习了,现在对这一块的原理就比较清楚了。

学习了,谢谢

嘿嘿,D师兄开个PHP教程吧,俺来学习。

我觉得对以下三点有所了解,这个题就很自然很简单了:
1、zend的zval(struct _zval_struct)的定义
2、foreach是复制还是引用
3、PHP的copy on write、change on write和reference counter机制

博主的博客好久没有更新了 不知最近在忙些什么

谢谢关注。

个人生活最近一年基本没有什么变化,工作依旧,没有换过。只是有各种生活琐事,而且也在寻找、考虑个人发展的突破口。这样一来,就觉得可支配的剩余时间就少多了。网络是生活的一部分,但并非必需品,因此更新网站的频率就少多了(虽然我依然一直不时更新“我的百科”网页里面的年鉴部分来记录自己的日常琐事)。

祝你好运。

你好。
搜索TN visa时偶然发现你的网站,内容十分详尽。我在NM,现正在找工作,最近一年在做LAMP和Symfony的开发,不知道你们公司现在是否还在招人?

最近2年半一直在招PHP,不过最近好像刚把招人的广告给下了,可能是因为整体向Java转移的缘故。可以试着投一下简历,但最好PHP/Java俱佳。普通技术水平的话尽量就不要在这里混了,不是别的,不太好混。SellingSource.com。祝你好运

谢谢你的回复。不过,现在几乎所有的公司都在提高门槛,对于刚毕业的学生来说经验却还是原地踏步。所以只要是机会只能尽量尝试,至于技术是否普通,待实践去检验好了。

我一直想学PHP,自己也看了一段时间,可是没有程序不大,想参加个辅导班,以后也多来这个博客看看啊

添加新评论

友情提醒:您的言论自由在本站会得到充分保证;不过,由于广告留言等猖獗,因此本站的内容过滤系统有可能会暂时屏蔽您新发的留言或评论。不便之处,希望理解。