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