章 54. 使用 PHP本節彙集了你在寫 PHP 腳本時可能碰到的大多數普通錯誤。
PHP 提供很多「預定義變量」,例如超全局變量 $_POST。可以遍歷 $_POST 變量,因為它是一個和所有通過 POST 方法傳遞資料相聯繫的陣列。例如,可以用 foreach 簡單地遍歷它,檢查 empty() 值,以及將它們輸出。
函數 addslashes() 能夠實現這種動作。請參閱函數 mysql_escape_string()。另外,還可以用函數 stripslashes() 來去掉反斜線。
PHP 函數 stripslashes() 能夠從 string 中去掉所有的反斜線。這些反斜線出現最有可能的原因是 PHP 設定項 magic_quotes_gpc 被開啟。
在 PHP 中,一段代碼的結束旗標要麼是「?>」要麼是「?>\n」(\n 表示換行)。因此在上面的例子中,輸出的句子將顯示在同一行中,因為 PHP 忽略了代碼結束旗標後面的換行。這意味著若果要輸出一個換行符,需要在每段 PHP 代碼的結束旗標後面多加一個換行。 PHP 為什麼這麼做呢?因為在格式化標準的 HTML 時,這樣通常會更容易。假如輸出了換行而你不需要這個換行時,就不得不用一個非常長的行來達到這樣的效果,或是讓產生的 HTML 頁面的源檔案的格式很難讀。 6. 我得到訊息「Warning: Cannot send session cookie - headers already sent...」或是「Cannot add header information - headers already sent...」。 函數 header(),setcookie() 和 session 函數需要在輸出流中增加頭訊息。但是頭訊息只能在其它任何輸出內容之前傳送。在使用這些函數前不能有任何(如 HTML)的輸出。函數 headers_sent() 能夠檢查腳本是否已經傳送了頭訊息。請參閱輸出控制函數。 若果以 Apache 的模組模式運行 PHP,那麼函數 getallheaders() 可以做這件事。因此下面的代碼可以顯示所有的請求報頭:
請參閱函數 apache_lookup_uri()、apache_response_headers() 和 fsockopen()。 IIS 的安全模型這裡有毛病。這是所有 IIS 下運行的 CGI 程式所共有的問題。一個解決辦法是建立一個純 HTML 檔案(不經由 PHP 解析)作為要進入認證目錄的登入頁面,然後用 META 旗標來重導至 PHP 頁面,或是用一個連線到 PHP 頁面。然後 PHP 就可以正確識別認證訊息了。若果是用 ISAPI 模組,那沒有這個問題。其它 NT 下的 web 伺服器不受此影響。更多訊息見 http://support.microsoft.com/kb/q160422/及 HTTP 認證一章。 必須要做些修改。開啟 Internet 訊息服務,找到你的 PHP 檔案並開啟屬性頁,選取檔案安全性標籤,點閱匿名訪問和身份驗證控制的「編輯」按鈕。 解決此問題有兩個方法,一是不要選中匿名訪問並且選中整合 Windows 身份驗證,二是選中匿名訪問並編輯匿名訪問使用的帳戶,改成一個有權限的。 Netscape 在關於 HTML 旗標(例如 table)上比 IE 更嚴格。用一個 HTML 驗證器,例如 validator.w3.org 來驗證你的 HTML 輸出可能會有說明。例如漏了 </table> 可能會導致這樣的結果。 同樣,IE 和 Lynx 都忽略了 HTML 流中的任何 NULs(\0),Netscape 就不。最好的檢查方法是編譯 PHP 的指令行模式版本(也稱為 CGI 版本)並從指令行運行你的腳本。在 *nix 中,用管道傳遞到 od -c 並檢視任何 \0 字元。若果在 Windows 下你需要能夠檢視二進位檔案格式的編輯器或程式。當 Netscape 碰到 NUL 時就不會輸出之後該行的任何內容而 IE 和 Lynx 都會。 要能夠在 PHP 代碼中直接內嵌 <?xml,需要將 PHP 設定項 short_open_tags 設定為 0 以關閉短旗標格式。無法通過函數 ini_set() 來變更這項設定。不管 short_open_tags 是開或是關,都可以用類似於 <?php echo '<?xml'; ?> 的方法達到目的。該項設定的預設值為開。 最簡單的方法是讓 PHP 代碼也能使用 ASP 旗標。這可以讓你用 ASP 風格的 <% 和 %> 代碼定界符。一些流行的 HTML 編輯器在處理此格式上更加智慧化一些(目前如此)。要使用 ASP 風格的旗標,需要在 php.ini 中開啟 asp_tags,或是用相應的 Apache 配置選項。 請閱讀手冊中的預定義變量一章,該部分的文件已經包括了一部分可以用於你的腳本的預定義變量的清單。可用變量的完整清單(及更多訊息)可以通過呼叫 phpinfo() 函數來查閱。請務必閱讀手冊中來自 PHP 之外的變量一節,這部分文件闡述了外部變量的概念,例如來自 HTML 表單、Cookie 和 URL 的變量。
首先非常重要的一點是 PHP 設定項 register_globals 同樣會對伺服器端和環境變量產生影響。當 register_globals = off (從 PHP 4.2.0 開始其預設值為 off),變量 $DOCUMENT_ROOT 將不會存在,而只有 $_SERVER['DOCUMENT_ROOT']。若果 register_globals = on 則變量 $DOCUMENT_ROOT 和 $GLOBALS['DOCUMENT_ROOT'] 將同時存在。 若果確認 register_globals = on 但不知道為什麼 $DOCUMENT_ROOT 在函數內定不可用,這是因為它和其它的變量一樣需要在函數中執行 global $DOCUMENT_ROOT。請參閱手冊中的變量範圍一節。建議在 register_globals = off 的情況下進行編碼。
| ||||||||