正在学习PHP,写了几行代码总是出错,但是换一种方式就不出错了....求解释。。。。。

2011-03-16 12:39:05 +08:00
 yaocaptain
代码如下,把run()方法里面的foreach语句换成for就不会错了,但是foreach为什么会错我没搞懂:
<html>
<body>
<p>
<?php
//连接数据库
function db_connect(){
$result=new mysqli('localhost','***','******','*****');
if(!$result){
echo 'could not connect to db<br/>';
return false;
}else
return $result;
}
function get_lists(){
$db=db_connect();
$lists=array();
$query="select a ,b from a_table ";
$result=$db->query($query);
for($i=0;$i<$result->num_rows;$i++){
$row=$result->fetch_assoc();
array_push($lists,$row);
}
return $lists;
}

function run(){
$lists=get_lists();

foreach($lists as $e){
$e['c']=1;
}

// for($i=0;$i<sizeof($lists);$i++){
// $lists[$i]['c']=1;
// }
foreach($lists as $a){
echo $a['c']."<br/>";//就是这个地方经常跑出问题,说没有'c'这个Index.但是如果不用上面的
} //foreach语句,而是用注释掉的for语句的话就没有问题了

}

run();
?>
</p>
</body>
</html>
5820 次点击
所在节点    程序员
21 条回复
yesmeck
2011-03-16 12:49:31 +08:00
这是一个提醒而不是一个错误。
因为你的循环出来的$a里面没有带c这个key的值。
$query = "select a ,b from a_table ";
这里只有a,b两个key可以用。
yesmeck
2011-03-16 12:52:35 +08:00
哦,还有这句
foreach ($lists as $e) {
$e['c'] = 1;
}
这样$lists里面并不会多1这个值,
要这样
foreach ($lists as $key => $e) {
$lists[$key]['c'] = 1;
}
huacnlee
2011-03-16 13:59:50 +08:00
咋开始学PHP了啊
yaocaptain
2011-03-16 15:13:42 +08:00
@yesmeck
恩,我试了一下你的方法,果然'c'这个索引插进去了。然后我改了一下:
foreach ($lists as $key => $e) {
//$lists[$key]['c'] = 1;
$e['c']=1;
}
结果却没有插进去。$e应该等于$lists[$key]的啊?然后我又测了一下$e==$lists[$key],它们是相等的。而且$lists并不是一个关联数组,应该用这个foreach($lists as $e)的语句提取元素吧。。。是不是语法在这里有特殊的地方,还是我有地方理解错了?
benzhe
2011-03-16 16:01:38 +08:00
@yaocaptain $e 是$lists[$key] 的值
arikado
2011-03-16 16:28:57 +08:00
试试@@
foreach($lists as &$e){
$e['c']=1;
}
yesmeck
2011-03-16 16:31:51 +08:00
@yaocaptain
$e和$lists[$key]只是值相等而已,但内存里的存放位置是不同的

@arikado
这样是不行的。。。。
因为$e并不是数组。。。
yesmeck
2011-03-16 16:35:21 +08:00
额,= =@arikado 我说错了
arikado
2011-03-16 16:39:17 +08:00
@yesmeck -。-其实我只看了foreach里面那段......>.<~
yaocaptain
2011-03-16 16:40:23 +08:00
@benzhe
@yesmeck
$lists是一个存放数据库检索结果的二维数组,作为其中的元素$e和$lists[$key]都是一个关联数组,并不是基本类型。我以为它们共用的同一个数组,就像引用或指针一样的,无论使用哪个进行操作都会影响共用的数组.......这样的结果是不是意味着$e是$lists[$key]的完全copy,是两个值完全相同的数组?
yesmeck
2011-03-16 16:42:19 +08:00
是直传递的。
@arikado那样写就是引用了。
aligo
2011-03-16 16:51:35 +08:00
用array_map,通过FP方式来解决这个问题
$lists = array_map(function($e){
$e['c']=1;
return $e;
}, $lists);

无污染无副作用,不过用php来写这个实在太不美观了
还是应该造个php代码生成器
yaocaptain
2011-03-16 16:59:55 +08:00
@yesmeck
我试了一下,貌似@arikado那样写仍然是值传递:
<?php
$a=array(1,2,3);
$b=array(2,3,4);
$c=array();
array_push($c,$a);
array_push($c,$b);
foreach($c as $e){
$e[0]=7;
$e[1]=8;
$e[2]=9;
}
echo $c[0][0].$c[0][1].$c[0][2]."<br/>";
echo $c[1][0].$c[1][1].$c[1][2]."<br/>";

?>
这段代码最终输出的是:
123
234
foreach语句对$c没有进行任何修改
yaocaptain
2011-03-16 17:04:06 +08:00
@aligo 哈哈有同感!$号敲得我烦死了!
arikado
2011-03-16 17:08:01 +08:00
@yaocaptain 你这段foreach后面是这样($c as $e)而不是($c as &$e) ? 没有漏掉"&" ?
aligo
2011-03-16 17:08:48 +08:00
虽然php的垃圾回收挺不靠谱的,不过php脚本的执行通常是随着http请求结束
所以尽可能不要用引用传递什么的比较好,对于变量每次变更,按照php默认做法,都指向一个新的引用比较好

不过php实在太不美观,缺乏表现力,从这个常用的array_map就可以看出-A-

不知道楼主有兴趣没:http://v2ex.appspot.com/t/9646
aligo
2011-03-16 17:12:58 +08:00
楼主需求应该可以写成
lists = lists.map(_['c']=1)
美观直接一目了然,可惜只是我的YY
aligo
2011-03-16 17:16:01 +08:00
另外,连接在php中数据库应该用pdo比较好,fetchAll返回就是数组,不用手动遍历再push
yaocaptain
2011-03-16 17:17:26 +08:00
@arikado
- - 不好意思看漏了...多谢提醒!
yaocaptain
2011-03-16 17:25:28 +08:00
@aligo
http://v2ex.appspot.com/t/9646
我心有余而力不足,编程只是入门水平而已- -

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/9827

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX