使用 PHP

本節(jié)匯集了你在寫 PHP 腳本時可能碰到的大多數(shù)普通錯誤。

  1. 我忘了 PHP 函數(shù)的參數(shù)順序,它們是隨機(jī)的嗎?
  2. 我想寫一個可以處理任何表單來的數(shù)據(jù)的通用 PHP 腳本。我怎么知道哪個 POST 方法變量可用呢?
  3. 我需要在所有的單引號(')前加一個反斜線(\),使它們變成(\')。我如何能夠通過正則表達(dá)式來實現(xiàn)? 我同樣希望能夠?qū)?" 轉(zhuǎn)換成 \",將 \ 轉(zhuǎn)換成 \\。
  4. 當(dāng)我這樣做時,輸出顯示的次序是錯的: <?php function myfunc($argument) { echo $argument + 10; } $variable = 10; echo "myfunc($variable) = " . myfunc($variable); ?> 這是怎么回事?
  5. 下面代碼怎么沒有分成兩行顯示? <pre> <?php echo "This should be the first line."; ?> <?php echo "This should show up after the new line above."; ?> </pre>
  6. 我得到消息 “Warning: Cannot send session cookie - headers already sent...” 或者 “Cannot add header information - headers already sent...”。
  7. 我需要直接訪問請求報頭中的信息,怎么能辦到?
  8. 當(dāng)我用 IIS 進(jìn)行 HTTP 認(rèn)證時得到 “No Input file specified” 消息。
  9. Windows:不能訪問另一臺電腦上用 IIS 共享的文件。
  10. 我怎樣混合使用 XML 和 PHP?它不認(rèn)我的 <?xml 標(biāo)記!
  11. 哪里可以找到所有可用的 PHP 預(yù)定義變量的完整列表?
  12. 怎樣才能不用非免費(fèi)的商業(yè)庫(例如 PDFLib) 來生成 PDF 文檔?我想要個免費(fèi)的并且不需要再連接別的 PDF 庫。
  13. 有些 PHP 選項可以接受縮寫的字節(jié)值,與僅能接受 int 字節(jié)值相反。都有哪些縮寫字節(jié)值?
我忘了 PHP 函數(shù)的參數(shù)順序,它們是隨機(jī)的嗎?

PHP 是一個將數(shù)百個外部庫連接在一起的粘合劑,盡管有時候會有一些混亂。這里有一些簡單的經(jīng)驗法則:

數(shù)組函數(shù) 參數(shù)的順序為 "needle, haystack", 字符串函數(shù) 則相反,順序為 "haystack, needle"。

我想寫一個可以處理任何表單來的數(shù)據(jù)的通用 PHP 腳本。我怎么知道哪個 POST 方法變量可用呢?

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;
}
?>

我需要在所有的單引號(')前加一個反斜線(\),使它們變成(\')。我如何能夠通過正則表達(dá)式來實現(xiàn)? 我同樣希望能夠?qū)?" 轉(zhuǎn)換成 \",將 \ 轉(zhuǎn)換成 \\。

假設(shè)是針對數(shù)據(jù)庫,請使用數(shù)據(jù)庫自帶的轉(zhuǎn)義機(jī)制。比如,針對 MySQL 使用 mysql_real_escape_string() 函數(shù),針對 PostgreSQL 則使用 pg_escape_string() 函數(shù)。還有兩個標(biāo)準(zhǔn)函數(shù) addslashes()stripslashes() 可以在舊的 PHP 版本中實現(xiàn)類似的操作。

當(dāng)我這樣做時,輸出顯示的次序是錯的:
<?php
function myfunc($argument)
{
    echo 
$argument 10;
}
$variable 10;
echo 
"myfunc($variable) = " myfunc($variable);
?>
這是怎么回事?

要在一個表達(dá)式中(例如在上面的例子中和其它字符串連接)使用函數(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é)束標(biāo)記要么是“?>”要么是“?>\n”(\n 表示換行)。因此在上面的例子中,輸出的句子將顯示在同一行中,因為 PHP 忽略了代碼結(jié)束標(biāo)記后面的換行。這意味著如果要輸出一個換行符,需要在每段 PHP 代碼的結(jié)束標(biāo)記后面多加一個換行。

PHP 為什么這么做呢?因為在格式化正常的 HTML 時,這樣通常會更容易。假如輸出了換行而你不需要這個換行時,就不得不用一個非常長的行來達(dá)到這樣的效果,或者讓產(chǎn)生的 HTML 頁面的源文件的格式很難讀。

我得到消息 “Warning: Cannot send session cookie - headers already sent...” 或者 “Cannot add header information - headers already sent...”。

函數(shù) header(), setcookie()session 函數(shù)需要在輸出流中添加頭信息。但是頭信息只能在其它任何輸出內(nèi)容之前發(fā)送。在使用這些函數(shù)前不能有任何(如 HTML)的輸出。函數(shù) headers_sent() 能夠檢查腳本是否已經(jīng)發(fā)送了頭信息。請參閱 輸出控制函數(shù)。

我需要直接訪問請求報頭中的信息,怎么能辦到?

如果以 Apache 的模塊方式運(yùn)行 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()。

當(dāng)我用 IIS 進(jìn)行 HTTP 認(rèn)證時得到 “No Input file specified” 消息。

IIS 的安全模型這里有毛病。這是所有 IIS 下運(yùn)行的 CGI 程序所共有的問題。一個解決辦法是建立一個純 HTML 文件(不經(jīng)過 PHP 解析)作為要進(jìn)入認(rèn)證目錄的登錄頁面,然后用 META 標(biāo)記來重定向到 PHP 頁面,或者用一個連接到 PHP 頁面。然后 PHP 就可以正確識別認(rèn)證信息了。如果是用 ISAPI 模塊,那沒有這個問題。其它 NT 下的 web 服務(wù)器不受此影響。更多信息見 ? http://support.microsoft.com/kb/q160422/HTTP 認(rèn)證 一章。

Windows:不能訪問另一臺電腦上用 IIS 共享的文件。

必須要做些修改。打開 Internet 信息服務(wù),找到你的 PHP 文件并打開屬性頁,選擇 文件安全性標(biāo)簽,點擊 匿名訪問和身份驗證控制的“編輯”按鈕。

解決此問題有兩個方法,一是不要選中 匿名訪問并且選中 集成 Windows 身份驗證,二是選中 匿名訪問并編輯匿名訪問使用的帳戶,改成一個有權(quán)限的。

我怎樣混合使用 XML 和 PHP?它不認(rèn)我的 <?xml 標(biāo)記!

要能夠在 PHP 代碼中直接嵌入 <?xml,需要將 PHP 設(shè)置項 short_open_tags設(shè)置為 0以關(guān)閉短標(biāo)記格式。無法通過函數(shù) ini_set()來更改這項設(shè)置。不管 short_open_tags是開或者關(guān),都可以用類似于 <?php echo '<?xml'; ?>的方法達(dá)到目的。該項設(shè)置的默認(rèn)值為開。

哪里可以找到所有可用的 PHP 預(yù)定義變量的完整列表?

請閱讀手冊中的 預(yù)定義變量 一章,該部分的文檔已經(jīng)包含了一部分可以用于你的腳本的預(yù)定義變量的列表。可用變量的完整列表(及更多信息)可以通過調(diào)用 phpinfo() 函數(shù)來查閱。請務(wù)必閱讀手冊中 來自 PHP 之外的變量 一節(jié),這部分文檔闡述了外部變量的概念,例如來自 HTML 表單、Cookie 和 URL 的變量。

怎樣才能不用非免費(fèi)的商業(yè)庫(例如 PDFLib) 來生成 PDF 文檔?我想要個免費(fèi)的并且不需要再連接別的 PDF 庫。

有幾個選擇,例如 ? FPDF? TCPDF 模塊。

有些 PHP 選項可以接受縮寫的字節(jié)值,與僅能接受 int 字節(jié)值相反。都有哪些縮寫字節(jié)值?

可用的選擇有 K(對應(yīng) Kilobytes),M(對應(yīng) Megabytes)和 G(對應(yīng) Gigabytes),區(qū)分大小寫。其余的都認(rèn)為是字節(jié)。 1M等于一個 Megabyte,即 1048576 字節(jié)。 1K 等于一個 Kilobyte,即 1024 字節(jié)。不能在 php.ini 之外使用這些符號,最好用整數(shù)的 int 字節(jié)值。參見 ini_get() 文檔中的轉(zhuǎn)換示例。要注意,數(shù)字類型為 int 會自動取整,這意味著 0.5M0 是等價的。

注意: kilobyte 和 kibibyte 的區(qū)別

PHP 將一個千字節(jié)(kilobyte)描述為等于 1024 字節(jié)(bytes),而 IEC 標(biāo)準(zhǔn)則認(rèn)為這是一個 kibibyte。結(jié)論:k 和 K = 1024 bytes.