作者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