作者clifflu (缺钱啦 @@)
看板PHP
标题Re: [请益] 未定义的index?
时间Wed Oct 19 02:11:55 2005
※ 引述《andreli (推销相簿中!!)》之铭言:
: http://saygosh.com/homework/num/square.php
: 这个程式是一个高斯消去法
: 我想了很久也想不透为什麽在我电脑测试的时候会出现
: Notice: Undefined index: a34 in D:\webs\phptest\square.php on line 205
: Notice: Undefined index: a24 in D:\webs\phptest\square.php on line 216
: Notice: Undefined index: a14 in D:\webs\phptest\square.php on line 216
: 不过我直接在相同的地方使用echo $_POST['a34'];
: 确实有值存在
: 我用$_POST["a".$row.$column]却没有办法...
: 相同的程式码,直接使用随机的可以执行无误,
: 使用上传的档案,我想分析的部分应该没错,因为他也跑的出高思消去法
答案揭晓.... (我居然花这麽多时间搞这个.. 果然对常犯错误不太有 sense XD)
这个程式大致上的流程是
1) 判断资料是来自 POST 输入数字, 或是 POST 上传档案
2) 若为数字, 跳到 4
3) 若为档案, 则将档案内容读入 $_POST 中 (column, row, a11 ~ a34)
4) 根据 $_POST['aXX'] 以高斯法消去
5) 将消去後的方程式求出解.
这个程式主要出问题的那几行内容大概像是这样:
$x[$w]=(
$_POST["a".$row.$column]) / ($_POST["a".$row.$w]);
ok, 为什麽会有问题呢 ? 在上传档案时, $row, $column 直接来自档案之中,
而看起来又像是 a34, 但直接以之当作 key 传入, 又可以得到我们要的资讯.
所以问题到底出在哪边 ? 不会是 php 的 bug 吧 (_POST 不给写入 !!??)
结果当我把这行先手动处理成 $a = sprintf("a%1d%1d", $row, $column) 或是
sprintf("a%1s%1s", $row, $column) 却都能正常运作.
开始有人猜到了吧... $row 和 $column 的型态都是字串...
公布谜底:
$row 和 $column 是从档案中利用 file() 直接读入, 也没有转型成数字.
因此当 php 被要求以 . 处理这些变数时, 就被直接以字串型式引入了.
$row 是 String(1) "3", 但 $column 是 String(2) "4\0x0A"
就是那多出来的 0x0A 把 $_POST 的 key 弄坏掉.
为什麽在计算过程中都没出事呢 ?
因为其间你都是拿数字运算子丢给它, 那麽这两个变数 (其实还有所有的 aX4)
都会被当作变数. 其中 aX4 的值都会被覆写 (而成为数字),
剩下 $column 来变成 bug.
所以写 php 请千万注意以下几点:
1) 缩排要缩好: 没有人规定必需怎麽作, 但以一种易读的, 一致的风格书写,
能让自己或别人 debug 时轻松许多.
2) 变数名不要乱取: 除了 $row, $column, aXX, $matrix 以外, 我都看不懂 XD
3) 尽量将 php code 与 HTML code 分开, 没事插一堆 <?php ?> 在函式里很烦.
虽然 manual 有建议将需要程式判断的大量输出放在 ?> .... <? 之间能够节
省时间, 不过这样的 coding style 真的很难看 >_<
4) 将需要先行判断的 php code 放在档案的最开头是种不错的主意, 但请记得
html 4.0 的规定是 "把 <!DOCTYPE ... " 放在第一行.
仔细看看底下的 code 就会知道我在讲什麽了 (绿色的字代表 parse 过後的行数)
<?php
// 点点点
// 毛毛毛
?>
1
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
2
"
http://www.w3.org/TR/html4/loose.dtd">
5) 注解最好够多, 至少要够精要. 不要写废话, 例如
$fp = fopen("aaa.txt") ; // 读档案 <- 难不成是吃麻糬吗 XD
6) 即使 php 的型态很软弱, 你还是要注意它.
7) 任何来自 user input (file, Request ...) 的资料都需要特别注意.
8) 无论用 fgets(), file() 你都会把换行字元吃到里头, 顺手 trim() 一下吧.
--
鬼压床怎麽办
骑上去啊
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 140.112.217.134