PHP的十個進階技巧(中)
三、檔案是我們的朋友
無論你在開發的網站規模的大小,都應該意識到代碼重用的重要性,無論這些代碼是HTML、還是PHP代碼。例如,你必須至少每年改變一次包含著作權資訊的頁尾,如果你的網站含有1000個頁面,每年修改一次也是個很煩人的事兒。
在PHP中,至少有幾個函數可以協助你實現代碼重用的目的,所使用的函數取決於你所重用的代碼,主要的函數有:
* include() and include_once()
* require() and require_once()
include()函數包含並對給定的檔案進行計算,例如:
include('/home/me/myfile');
在include檔案中的任何代碼都在include()出現的代碼範圍內執行,你可以通過聯合使用include()和fopen()在自己的伺服器上包含靜態檔案,在另一台伺服器上包含目標檔案。
include_once()的功能與include()相同,二者之間的區別在於它會檢查一個檔案中的代碼是否已經包含在現有的指令碼中,如果代碼已經存在,則不會再次包含它。
require()函數用給定檔案的內容取代它本身,這一代替過程發生在PHP引擎編譯代碼期間,而不是在執行期間進行,它不象include()那樣會首先進行計算。require()函數更多地用在靜態元素中,而include()更多地用於動態元素中。與include_once()類似的是,require_once()將首先檢查是否已經插入給定的代碼,如果代碼已經存在,就不再插入了。
為也瞭解其內容,在著作權資訊、靜態文字和其他不包含變數的元素或者依賴其他正在執行的指令碼的元素中我更趨向於使用require函數。例如:
Something
[a lot of content]
// insert copyright
require('/home/me/mycopyright');
?>
另一方面,我經常在檔案的開始使用include()來控制許多的函數:
//得到函數庫
include('/home/me/myfunctions');
// do PHP things with my functions ?>
Something
[a lot of content]
下一個問題就該是“include和require檔案在哪裡?”,對這個問題簡單的回答是,“系統中的任意地方。”如果你的代碼中包含有帶有使用者名稱和口令的資料庫連接,你肯定不會將它們都放在主目錄中向所有的人都開放。
included或required檔案可以在系統上的任何地方,只要PHP啟動並執行系統上的使用者可以訪問這些檔案即可,你可以使這些檔案具有任何尾碼,或者不使用尾碼。
使用include()和require()對在網站中的元素進行具體化是一種普遍的現象,並在需要對網站升級時,給你帶來很大的方便。
四、PHP和檔案系統的維護
PHP中有許多與檔案系統有關的函數,這些函數不僅可以開啟檔案,還可以顯示目錄中的內容、移動檔案和其他一些功能,許多人甚至用PHP開發基於互連網的檔案總管。
關於檔案路徑的解釋:在Windows中,可以在路徑中使用/和\符號,而在其他的作業系統中只能使用/符號。出於一致性的緣故,我們統一使用/符號。
下面的指令碼範例可以顯示一個目錄清單,注釋已經包含在代碼中:
$dir_name = "/home/me/";
/* 建立一個控制代碼,其值是開啟一個給定目錄的結果*/
$dir = opendir($dir_name);
/* 建立一個文字塊,用以放置列表元素(檔案名稱字)*/
$file_list = "
";
/* 使用一個while語句,讀取已經開啟的目錄中的所有元素,如果檔案的名字不是“.”或“..”,則顯示列表中的名字*/
while ($file_name = readdir($dir)) {
if (($file_name != ".") && ($file_name != "..")) {
$file_list .= "
- $file_name";
}
}
$file_list .= "
";
/*關閉開啟的目錄,結束PHP模組*/
closedir($dir);
?>
Directory Listing
Files in:
好了,我們已經得到了一個目錄清單。需要注意的是,要讀取一個檔案(稍後我們將進行講解)或目錄的內容,PHP啟動並執行系統上的使用者必須至少有讀取檔案的許可權。
下面是一個如何拷貝檔案的例子:
$original = "/home/me/mydatabasedump";
$copied = "/archive/mydatabasedumo_1010";
/* 使用copy()函數拷貝原始檔案,如果拷貝沒有完成則會顯示一個錯誤資訊*/
@copy($original, $copied) or die("Couldn't copy file.");
?>
這個例子是一個檔案備份系統的原型。在這段指令碼運行時,它把檔案拷貝到一個不同的位置進行儲存。稍微修改一下精靈,就可以在一天中你指定的時刻執行它,而無需使用者的幹預。
假定你在系統上安裝了Lynx,可以建立一個精靈的條目訪問這個檔案,訪問這個檔案會運行這個指令碼並建立一個拷貝檔案,下面的例子將在上午5點鐘運行這個指令碼,然後關閉Lynx:
0 5 * * * [username] lynx -dump http://localhost/copyfile.php 1>/dev/null 2>&1
如果啟動並執行是CGI版本的PHP,可以跳過Lynx部分,而直接調用二進位檔案:
0 5 * * * [username] php /path/to/copyfile.php 1>/dev/null 2>&1
五、豐富的數組函數
PHP 4.0中新添加了30個與組數有關的函數,其中一些常見的函數可以判斷一個數組中是否包含某個元素,對一個數組中的元素進行計數,添加或刪除數組中的元素或者對數組中的元素進行排序。
如果有一個很大的數組,而你需要找出其中是否包含一個特定的元素,就可以使用in_array()。下面的例子將顯示“Not found in this array”,因為在一個名字為$namesArray的數組中尋找Albert,而在$namesArray數組中不存在這樣一個元素。
$lookingFor = "Albert";
if (in_array($lookingFor, $namesArray)) {
echo "You've found it!";
} else {
echo "Not found in this array!";
}
?>
如果把$lookingFor的值改為Mary,就會得到“You've found it!”的資訊,因為Mary是$namesArray數組中的一個元素。
如果要對一個數組中的元素個數進行計數,只要簡單地使用count()函數即可:
$count = count($namesArray); ?>
返回的$count的值為7。
可以在一個數組的開頭或結尾處添加元素,還可以使用array_merge()來建立一個包含二個或更多數組中元素的新數組,合并時,元素的順序會按指定的順序排列,如果原來的數組是被排過序的,在合并後需要對它重新排序。
我們可以首先利用array_push()在數組的結尾處添加一個元素:
$fruitArray = array("apple", "orange", "banana", "kiwi", "pear");
/* 向數組中添加元素 */
array_push($fruitArray, "grape", "pineapple", "tomato");
/*顯示每個元素及其序號*/
while (list($key,$value) = each($fruitArray)) {
echo "$key : $value
";
}
?>
運行上面的程式將得到下面的結果:
0 : apple
1 : orange
2 : banana
3 : kiwi
4 : pear
5 : grape
6 : pineapple
7 : tomato
如果需要在數組的開頭添加元素,其代碼與上面的代碼差不多,唯一的不同之處是需要用array_unshift()代替array_push()。
/* 建立一個數組*/
$fruitArray = array("apple", "orange", "banana", "kiwi", "pear");
/* 向數組中添加元素*/
array_unshift($fruitArray, "grape", "pineapple", "tomato");
/* 顯示每個元素及其序號*/
while (list($key,$value) = each($fruitArray)) {
echo "$key : $value
";
}
?>
運行上面的程式將得到下面的結果:
0 : grape
1 : pineapple
2 : tomato
3 : apple
4 : orange
5 : banana
6 : kiwi
7 : pear
array_merge()函數可以把二個或更多的數組合并為一個數組。
$fruitArray = array("apple", "orange", "banana", "kiwi", "pear");
/*/建立第二個數組*/
$vegArray = array("carrot", "green beans", "asparagus", "artichoke", "corn");
/*把這二個數組合并為一個數組*/
$goodfoodArray = array_merge($fruitArray, $vegArray);
/* 顯示每個元素及其序號*/
while (list($key,$value) = each($goodfoodArray)) {
echo "$key : $value
";
}
?>
運行上面的指令碼將得到下面的結果:
0 : apple
1 : orange
2 : banana
3 : kiwi
4 : pear
5 : carrot
6 : green beans
7 : asparagus
8 : artichoke
9 : corn
現在我們已經掌握了如何添加元素和合并數組,我們再來看看如何從一個數組中刪除元素。從一個數組的末尾刪除一個元素可以使用array_pop()函數,使用array_shift()函數可以從一個數組的開頭刪除一個元素。儘管使用array_pop()或 array_shift()從數組中刪除了一個元素,你還可以把這個元素當作一個變數來使用。
使用array_pop()從一個數組的末尾刪除一個元素:
/*建立一個數組*/
$fruitArray = array("apple", "orange", "banana", "kiwi", "pear");
/* 從數組的末尾刪除一個元素*/
$popped = array_pop($fruitArray);
/* 顯示刪除後數組的內容和你刪除的元素*/
while (list($key,$value) = each($fruitArray)) {
echo "$key : $value
";
}
echo "
and finally, in $popped: $popped";
?>
運行上面的指令碼會得到下面的結果:
0 : apple
1 : orange
2 : banana
3 : kiwi
and finally, in $popped: pear
我們再來討論一個從一個數組的末尾刪除元素的例子:
/* 建立一個數組*/
$fruitArray = array("apple", "orange", "banana", "kiwi", "pear");
/*從一個數組的開始刪除一個元素*/
$shifted = array_shift($fruitArray);
/* 顯示刪除後數組的內容和你刪除的元素*/
while (list($key,$value) = each($fruitArray)) {
echo "$key : $value
";
}
echo "
and finally, in $shifted: $shifted";
?>
運行上述指令碼會得到如下的顯示結果:
0 : orange
1 : banana
2 : kiwi
3 : pear
and finally, in $shifted: apple
另外還有幾個函數可以對數組中的元素進行排序,但在這裡我們將只簡要介紹基本的排序函數,說明排序的過程:
$fruitArray = array("apple", "orange", "banana", "kiwi", "pear");
/* 對數組進行排序*/
sort($fruitArray);
/*顯示每個元素及其序號*/
while (list($key,$value) = each($fruitArray)) {
echo "$key : $value
";
}
?>
運行上述的指令碼會得到如下的顯示結果:
0 : apple
1 : banana
2 : kiwi
3 : orange
4 : pear