先上源代码:
<!DOCTYPE html> <head> <title>实验</title> <meta charset="utf-8"> <style> th{ width:100px; } </style> </head> <body> <h4 style="margin-left:230px">请输入学生信息</h4> <table border="0"> <form method="post" action=""> <tr> <td ></td> <td>学号</td> <td>姓名</td> <td>成绩</td> </tr> <tr> <td>学生1:</td> <td><input type="text" name="stu0_num"></td> <td><input type="text" name="stu0_name"></td> <td><input type="text" name="stu0_score"></td> </tr> <tr> <td>学生2:</td> <td><input type="text" name="stu1_num"></td> <td><input type="text" name="stu1_name"></td> <td><input type="text" name="stu1_score"></td> </tr> <tr> <td>学生3:</td> <td><input type="text" name="stu2_num"></td> <td><input type="text" name="stu2_name"></td> <td><input type="text" name="stu2_score"></td> </tr> <tr> <td>学生4:</td> <td><input type="text" name="stu3_num"></td> <td><input type="text" name="stu3_name"></td> <td><input type="text" name="stu3_score"></td> </tr> <tr> <td>学生5:</td> <td><input type="text" name="stu4_num"></td> <td><input type="text" name="stu4_name"></td> <td><input type="text" name="stu4_score"></td> </tr> <tr> <td></td> <td><input type="submit" name="submit" value="提交"></td> <td></td> <td><input type="reset" name="reset" value="重置"></td> </tr> </form> </table> <?php #储存学生信息的临时数组 $arr= array( range(1,3), range(1,3), range(1,3), range(1,3), range(1,3) ); if (isset($_POST['submit'])) { #如果提交了内容,将内容通过foreach函数,存放在数组当中 foreach ($arr as $key => &$table) { //$table[$key] = $_POST["stu${key}_num"]; $table[0] = $_POST["stu${key}_num"]; $table[1] = $_POST["stu${key}_name"]; $table[2] = $_POST["stu${key}_score"]; } #根据成绩对学生信息进行排序 /*foreach ($arr as $key => $table) { $sort[$key] = $table[2]; } array_multisort($sort,SORT_DESC,$arr);*/ var_dump($arr); #打印出最终的结果 echo " <table border='1'>"; echo "<tr><th>学号</th><th>姓名</th><th>成绩</th></tr>"; foreach ($arr as $table) { echo "<tr>"; foreach ($table as $value) { echo "<td>$value</td>"; } echo "</tr>"; } echo "</table>"; var_dump($arr); } ?> </body> </html>要实现的功能,只是简单的学生信息收集,并按照收集的学生成绩排序,并打印成单个列表,功能如下图: 虽然功能简单,但是不免可以发现其中的问题。如 我输入的信息原本并不一致的,但是发现,这里竟然发生了意外。两条数据竟然数据一致了。
为了证明不是我的问题,我们接下来进行研究这个问题所出现的原因。
var_dump($arr);#var_dump一下同一个数据 #打印出最终的结果 echo " <table border='1'>"; echo "<tr><th>学号</th><th>姓名</th><th>成绩</th></tr>"; foreach ($arr as $table) { echo "<tr>"; foreach ($table as $value) { echo "<td>$value</td>"; } echo "</tr>"; } echo "</table>"; var_dump($arr);#var_dump一下同一个数据然后再次重新刷新我们的页面,也就是重新提交表单 上边是我提交的正常的数据,下边是“变化”后。也就是这个“变化”,足以证明我输入的数据是不一样的,但是在打印成为表单的过程中,自动对值进行了改变。
既然与我所设想的结果不一样,那么肯定就是我的代码哪个地方出现了问题。是哪里呢?
我原来认为是两个var_dump函数之间打印的代码出了问题。
但经过询问和自己的一番研究发现,问题的所在是在这:
foreach ($arr as $key => &$table) {#这里的&符号是错误关键 //$table[$key] = $_POST["stu${key}_num"]; $table[0] = $_POST["stu${key}_num"]; $table[1] = $_POST["stu${key}_name"]; $table[2] = $_POST["stu${key}_score"]; }查网上的资料,我对&符号的大致的了解是c/c++指针,指向地址,这样使用一个变量,相当于是另一个变量的变名。
也正是把c/c++等同起来,才造成了这次错误的出现。
下面是研究过程中的的代码:
<?php #先看这一段 $arr = [1,2,3]; $b = "hello"; $value = &$b; echo "$value<br>"; foreach ($arr as $key => $value) { echo "$b"; echo $value."<br>"; } ?>输出的结果是: hello 11 22 33
可见 b 的 值 , 在 遍 历 数 组 b的值,在遍历数组 b的值,在遍历数组arr的过程中,也发生了变化。
再看我们的另一段代码,也就是跟我最初的代码类似的代码:
$arr = [1,2,3]; foreach ($arr as $key => &$value) {#同样的地方,同样的&用法 echo $value."<br>"; } var_dump($value); foreach ($arr as $key => $value) { echo $value; //$value = "hello"; echo $arr[2]; echo "<br>"; } var_dump($arr); $value = 3; echo $arr[2];输出的结果是 1 2 3 D:\wamp64\www\test\2.php:196:int 3
11 22 22 D:\wamp64\www\test\2.php:204: array (size=3) 0 => int 1 1 => int 2 2 => int 2
3
不难发现,其实在我们第一个foreach()遍历完数组,其实我们并没有定义的变量$value仍还存在着。
而且$value的内存其实是储存着$arr[2]的地址,当我们假装$value这个值不存在时,再次使用$value用foreach去遍历另一个数组,as $value,相当就是给 $arr[2] = $arr 2[0] $arr[2] = $arr 21] $arr[2] = $arr 2[1] 这样的一次次,赋值,虽然我们在遍历,但是同时也在改变$arr[2]的值。
