本節(jié)匯集了你在寫 PHP 腳本時可能碰到的大多數(shù)普通錯誤。
PHP 是一個將數(shù)百個外部庫連接在一起的粘合劑,盡管有時候會有一些混亂。這里有一些簡單的經(jīng)驗法則:
數(shù)組函數(shù) 參數(shù)的順序為 "needle, haystack", 字符串函數(shù) 則相反,順序為 "haystack, needle"。
PHP 提供很多“ 預(yù)定義變量”,例如超全局變量 $_POST??梢员闅v $_POST變量,因為它是一個和所有通過 POST 方法傳遞數(shù)據(jù)相聯(lián)系的數(shù)組。例如,可以用 foreach簡單地遍歷它,檢查 empty()值,以及將它們輸出。
<?php
$empty = $post = array();
foreach ($_POST as $varname => $varvalue) {
if (empty($varvalue)) {
$empty[$varname] = $varvalue;
} else {
$post[$varname] = $varvalue;
}
}
print "<pre>";
if (empty($empty)) {
print "None of the POSTed values are empty, posted:\n";
var_dump($post);
} else {
print "We have " . count($empty) . " empty values\n";
print "Posted:\n"; var_dump($post);
print "Empty:\n"; var_dump($empty);
exit;
}
?>
假設(shè)是針對數(shù)據(jù)庫,請使用數(shù)據(jù)庫自帶的轉(zhuǎn)義機制。比如,針對 MySQL 使用 mysql_real_escape_string() 函數(shù),針對 PostgreSQL 則使用 pg_escape_string() 函數(shù)。還有兩個標準函數(shù) addslashes() 和 stripslashes() 可以在舊的 PHP 版本中實現(xiàn)類似的操作。
<?php
function myfunc($argument)
{
echo $argument + 10;
}
$variable = 10;
echo "myfunc($variable) = " . myfunc($variable);
?>
要在一個表達式中(例如在上面的例子中和其它字符串連接)使用函數(shù)的結(jié)果,需要 return 這個值,而不是 echo 它。
<pre>
<?php echo "This should be the first line."; ?>
<?php echo "This should show up after the new line above."; ?>
</pre>
在 PHP 中,一段代碼的結(jié)束標記要么是“?>”要么是“?>\n”(\n 表示換行)。因此在上面的例子中,輸出的句子將顯示在同一行中,因為 PHP 忽略了代碼結(jié)束標記后面的換行。這意味著如果要輸出一個換行符,需要在每段 PHP 代碼的結(jié)束標記后面多加一個換行。
PHP 為什么這么做呢?因為在格式化正常的 HTML 時,這樣通常會更容易。假如輸出了換行而你不需要這個換行時,就不得不用一個非常長的行來達到這樣的效果,或者讓產(chǎn)生的 HTML 頁面的源文件的格式很難讀。
函數(shù) header(), setcookie() 和 session 函數(shù)需要在輸出流中添加頭信息。但是頭信息只能在其它任何輸出內(nèi)容之前發(fā)送。在使用這些函數(shù)前不能有任何(如 HTML)的輸出。函數(shù) headers_sent() 能夠檢查腳本是否已經(jīng)發(fā)送了頭信息。請參閱 輸出控制函數(shù)。
如果以 Apache 的模塊方式運行 PHP,那么函數(shù) getallheaders() 可以做這件事。因此下面的代碼可以顯示所有的請求報頭:
<?php
$headers = getallheaders();
foreach ($headers as $name => $content) {
echo "headers[$name] = $content<br />\n";
}
?>
請參閱函數(shù) apache_lookup_uri()、 apache_response_headers() 和 fsockopen()。
IIS 的安全模型這里有毛病。這是所有 IIS 下運行的 CGI 程序所共有的問題。一個解決辦法是建立一個純 HTML 文件(不經(jīng)過 PHP 解析)作為要進入認證目錄的登錄頁面,然后用 META 標記來重定向到 PHP 頁面,或者用一個連接到 PHP 頁面。然后 PHP 就可以正確識別認證信息了。如果是用 ISAPI 模塊,那沒有這個問題。其它 NT 下的 web 服務(wù)器不受此影響。更多信息見 ? http://support.microsoft.com/kb/q160422/ 及 HTTP 認證 一章。
必須要做些修改。打開
Internet 信息服務(wù)
,找到你的 PHP 文件并打開屬性頁,選擇
文件安全性
標簽,點擊
匿名訪問和身份驗證控制
的“編輯”按鈕。
解決此問題有兩個方法,一是不要選中
匿名訪問
并且選中
集成 Windows 身份驗證
,二是選中
匿名訪問
并編輯匿名訪問使用的帳戶,改成一個有權(quán)限的。
要能夠在 PHP 代碼中直接嵌入 <?xml,需要將 PHP 設(shè)置項
short_open_tags設(shè)置為
0
以關(guān)閉短標記格式。無法通過函數(shù)
ini_set()來更改這項設(shè)置。不管
short_open_tags是開或者關(guān),都可以用類似于
<?php echo '<?xml'; ?>
的方法達到目的。該項設(shè)置的默認值為開。
請閱讀手冊中的 預(yù)定義變量 一章,該部分的文檔已經(jīng)包含了一部分可以用于你的腳本的預(yù)定義變量的列表??捎米兞康耐暾斜恚案嘈畔ⅲ┛梢酝ㄟ^調(diào)用 phpinfo() 函數(shù)來查閱。請務(wù)必閱讀手冊中 來自 PHP 之外的變量 一節(jié),這部分文檔闡述了外部變量的概念,例如來自 HTML 表單、Cookie 和 URL 的變量。
可用的選擇有 K(對應(yīng) Kilobytes),M(對應(yīng) Megabytes)和 G(對應(yīng) Gigabytes),區(qū)分大小寫。其余的都認為是字節(jié)。
1M
等于一個 Megabyte,即
1048576
字節(jié)。
1K
等于一個 Kilobyte,即
1024
字節(jié)。不能在 php.ini 之外使用這些符號,最好用整數(shù)的
int 字節(jié)值。參見
ini_get() 文檔中的轉(zhuǎn)換示例。要注意,數(shù)字類型為
int 會自動取整,這意味著
0.5M
與 0
是等價的。
注意: kilobyte 和 kibibyte 的區(qū)別
PHP 將一個千字節(jié)(kilobyte)描述為等于 1024 字節(jié)(bytes),而 IEC 標準則認為這是一個 kibibyte。結(jié)論:k 和 K = 1024 bytes.