函數的定義與應用
本章重點
2 使用內建的PHP函數
2 瀏覽線上函數手冊
2 使用者定義函數
2 進價技巧:可變參數、參價引呼叫與可變函數
任何程式語言都有某種程式抽象處理能力(procedural abstraction,就是幫程式碼某段區塊命名,以便在編寫其它程式碼區段時能夠取用)。某些script語言缺乏這種能力,而根據我們的經驗,這會使複雜的伺服端程式碼很快變得無法管理。
PHP用來提供這種抽象處理的機制就是函數(function)。 PHP中其實有兩種類型的函式,一種是已經由PHP開發者內建在語言中,另一種是由每個PHP程式設計師自己定義的。
本章中,我們來看看如何使用PHP已提供的大量函式,然後再學習如何定義屬於自己的函數。很幸運地,使用內建函數和自己定義的函數並沒有什麼不同。
使用函數
使用(或呼叫)函數的基本語法如下:
function_name(expression_1, expression_2,…,expression_n)
號以交換它是函數編號式,(稱為函數參數)列表的型式出現。根據具體定義,呼叫函數可以不帶參數,也可以同時帶入多個參數。
當PHP遇到有函數呼叫,它首先對每個參數運算式評算求值,然後使用這些值做為該函數的輸入。函數執行後,回傳值(如果有回傳值)就是整個函數運算式的結果。
下面所列出的範例都是PHP內建函數的有效呼叫方式:
sqtr(9) //平方根函數,結果是「3」
rand(10,10+10) / /回傳介於「10」與「20」之間的數值
strlen(“This has 22 characters”) //回傳數值「22」
pi() //回傳p的近似值
這些函數分別用1,2,1和0個參數來呼叫。
回傳值與附帶作用
每個函數呼叫都算是一個PHP運算式(與其它運算式一樣),在程式碼中包含函數只有兩個原因:為了取得回傳值,或者為了得到附帶作用。
函式的回傳值是函數運算的值。使用這個值,可以像使用其它任何運算式的求值結果一樣,例如,可以把它指定到某個變數,如下所示:
$my_pi = pi();
或者,可以把它嵌入複雜的運算式中,如下所示:
$approx = sprt($approx)* sqrt($approx)
函式還可以用來實現各種不同的附帶作用,其中包括將資料寫入檔案、資料庫操作以及把內容輸出顯示在瀏覽器視窗上。同時使用回傳與附帶作用出是可行的,例如,我們常常使用一個附帶作用的函數並同時回傳值來檢查這個函數是否執行正常
。
函式的結果可以是任何型別,通常都把array型別用來當成傳回多個值的函數。
函式手冊
PHP的架構設計得很聰明,讓它很容易由其它開發人員進行擴展延伸。其本的PHP語言本身就很容易懂,出很有彈性,大多數PHP功能都存在大量的內建函數中。這是指開發人員可以自由添加新的內建函式,並且能夠為PHP有所貢獻,這種方式非常好,因為它不會改變PHP使用者可能依賴的任何部分。
雖然本書涵盍了許多內建函式,對其中某些函數的講解比線上手冊的講解更詳細,但http://www.php.net所提供的手冊還是函數資訊的重要參考資源。在本書中,我們會在某種程度上摘選我們想要的主題來延伸介紹,而PHP手冊的內容仍舊是PHP在每個方面上最完整的參考。雖然我們希望跟隨PHP的未來版本即時更新本書,但線上說明還是會關於PHP新功能的最新功能的最新資訊,包括那些仍處於正在開發狀態的功能。所以有空看看PHP官方網站和線上提供的不同資源可是非常有幫助的。
雖然下面的資訊在本書結稿時是正確的(第二版再版的時間是2002年)。但可能有些細節部位已過時,或是因為線上手冊有了更新版本或重新組織而不再適用。
想要查詢線上手冊,可進入http://www.php.net網站,並選取右上方導覽列中的「documentaion」選項標籤,這樣會前往一個含有各種格式且包含民其使用手冊資訊的連結。我們想要看的是線是可註解的使用手冊(目前連接位置在Documentation網頁的View Online選項上),該手冊允許用戶把自己的註解資料張貼到每一頁中。 [請注意:手冊註解系統不是張貼問題的地方!如果有使用上的疑問,可參考郵寄清單(mailing list)部份,它位於www.php.net的「support」選項標籤中,或參考本書有關PHP資源的附錄D。手冊註解系統是在使用者自己理解後要用自己的話進行解釋和提出意見的地方,不過確是我們能做出貢獻的途徑,這也是有可能就會變成未來的正式版本,這的確是我們能做出貢獻的好途徑,這也是指出易混淆與可能有問題的好地方,不過這裡都以「英文」來溝通哦! ]
使用手冊中的絕大部分是函式的考次料,其中每個內建函式都有單獨一份說明頁。每頁從函式名稱和單行的說明開始,然後是屬於C語言風格的函數標頭宣告(下一節會講解到),後面是個稍長的說明,可能還有一兩個例子,然後(在註解手冊中)是來自使用者的註解和意見報告。
在手冊中的標頭
對於那些不熟悉C語言函數標頭的人,函數手冊的最開頭份可能會看不懂。基底格式是:
return-type function-name(typle argl,type2 arg2,…);
它指示了期望的函數回傳值型值,函數名稱和期望的參數類型等。
下面是個基本標頭描述:
string substr (string string,int startl [,int length]);
這就表示函數substr會傳回一個字串,並期望取得一個字串和兩個整數為參數。實際上,length兩邊的方括號表示了這個參數是選擇性的,因此在呼叫substr時,可帶一個string字串和一個int整數,或是帶一個string字串和兩個int整數。
與在C語言中的情況不同,這些手冊標頭中宣告的參數型別並非是絕對必要的。如果用一個數字當成一個參數來呼叫substr,也不會有錯誤出現,它是由 PHP在開始執行函數之前,先把第一個參數轉換成字串。不過參數型別的確表現了函式創造者的初衷,另外最好是按照手冊中註明的型別來使用函式,或者對型別轉換的有關事項要有足夠的了解,這樣才能夠保得到預期的結果。
一般來說,函數手冊中使用的類型名稱是六種基本類型之一,或是用它們的別名:integet(或int)、double(或float、real)、 Boolean、string、array 、object、resource和NULI。另外,可以看到void和mixed的類型。 Viod型態的函數根本不傳回任何值,而mixed參數類型意味著參數可以是任何類型。
查詢函數手冊
在手冊中查詢關於某函數的資訊的最佳途徑是什麼?這主要取決於你的好奇心和有興趣的部分是那種?關於函數最常見的問題是:
我要用X函數,它又該如何使用呢?
我需要完成某項Y任務,有函數能幫我完成這項任務嗎?
對於第一種情況,完整版本的線上手冊提供民根據函數名稱的自動查詢。在右上方導覽列下面,「search for」文字方塊預設搜尋的模式是函數的名稱,並且會在找到該函數後顯示此函數顯示此函數的網頁(你也可以選取其它搜尋對象,包含整個網站的mailing list,這裡是當你不知道所需函數名稱時,但是可以猜出所需函數的概略字樣時搜尋的好地方)。
以第二種情況來尋找的話,最好是使用函數參考文獻(Funcrion Reference ,PHP手冊中的其中一篇)的層次組織結構,該函數參考文獻分成108章。例如,前面提到的substr函數在「Headers in Documentation」部分內的「String functions」部分。讀者可以瀏覽函數參考文獻的章節列表,以選擇最適合你要完成的任務所屬的那一章。或者,如果剛好知道一個函數的名字,該函數可能與完成的工作處於同一範圍領域,此時就可以直接按下Quick Ref按鈕連接到相關章節。
使用者定義的函數
使用者定義的函數在PHP中並非必要的。你也可以只用基本的語言結構和大量內建函數就能夠建構出有用的Web網站了。不過如果發現自己的程式碼內容變得越來越長了,而且愈來愈難了解和管理時,這表示要想一想應該把自己的某些程式碼轉成函數了。
什麼是函數?
函數就中一種包裹某段程式碼區塊並給它取個名字的程式寫法,這方便於以後只用一行程式碼就能夠使用該程式碼區塊。假如在寫程式時,在多處都要使用到該程式碼區塊時,函數是最有效的方式,不過即使只使用一次,函數的建立與編寫也會對程式結構有所幫助,因為可以使你的程式碼更具可讀性。
函數定義語法
函數可定義為以下形式:
function function-name($argument1, $argument2,..)
{
statement1;
statement1;
函數定義有四個部份:
專用的「function」一詞
幫函式取的名稱
函式的參數清單(以逗號分隔的$符號變數)
函式本體(大括號內的一系列敘述語句)
和變數名稱一樣,函數名稱也必須由英文字母、數字和底線(_)組成,而且它不能以數字當開頭。與變數名稱不同的是,函數名稱在儲存前會被轉換成小寫,因此可將函數名稱視為不區分大小寫。
當呼叫使用定義的函數時發生的情況簡述如下:
1. PHP會依照名字找出該函數(如果函數還沒被定義過,則會顯示錯誤訊息)。
2. PHP把參數(或稱為「實際參數」)的值取代函數定義中參數清單裡的變數(或稱為「形式參數」)。
3. 執行函數本體的敘述語句。如果執行到敘述中「return」語句,則函數會停止執行並傳回指定的值。否則,函數會一直執行到最後一道,且不傳回任何值。
請小心,有經驗的程式設計師也許會注意到,前面的說明暗示了其為按值呼叫(call-by-value),而不是按參引呼叫(call-by-reference)。在本章最後一節會說明它們的差別,並示範如何進行按參引來呼叫。
函式定義的範例
舉一個虛構的例子,請設想下面的這段程序碼,目的是幫助我們決定購賣多少瓶裝飲料(也許未來的什麼時候,超市老品就已在使用可摧式的無線網頁瀏覽器查看比較採買的價格了)。
$liters_1 = 1.0;
$price_1 = 1.59;
$liters_2 = 1.5;
$price_2 = 2.09;
$price_2 = 2.09;
1
= $price_2 / $liters_2;
if($per_literl
print(“The first deal is better! ”);
else
print(“The second deal is b bjid!這種類型的比較在我們的Web網頁程式碼中隨處可見,我們很想把它做成可重複使用的函數。這樣做的一種方法是按照範例來重寫:
function better_deal ($amount_1,$price_1,
$amount_2,$price_2)
{
= $price_2/$amount_2;
return($per_amount_1
}
$liters_1 = 1.0;
_$price_1 = 1.59; 2.09;
if(better_deal($liters_1,$price_1,
$liters_2,$price_2))
print(“The first deal is better!”);
elsepum b !”);
better_deal函數抽取了以前程式碼中進行算術運算和比較的那三行程式碼,它帶有四個數字當作參數,並傳回一個Boolean 運算式的值。和任何其它Boolean值一樣,可以把它嵌入到if敘述的測試部份。雖然這個函數比原來的程式碼還長,但這樣重寫後有兩個優點:可以在程式其它多個位置使用這個函數(節省了整體程式行數),如果決定改變計算方式,只需要修改一個地方就好了。
還有一個替代方案,如果價格比較就是為了印出哪筆交易比較划算,那可以直接把輸出顯示敘述句放到函數裡,如下所示:
function print_better_deal($amount_1,$price_1,
$amount_2,$price_2)
{
$amount_2,$price_2)
{
$per_amount_1 = $price_1 / $amount_1;
$per_amount_2 = $price_2 / $98; (“The first deal is better!”);
else
print(“The second deal is better!”);
}
$liters_1 = 1.0;
}
$liters_1 = 1.0;
}
$liters_1 = 1.0;
. liters_2 = 1.5;
$price_2 = 2,09;
print_better_deal($liters_1,$price_1,
$liters_2,$price_2);
用結果發送結果第一個函數將結果發送到第一個函數,然後使用其中一個用於在一個if敘述的測試中。第二個函數沒有return語句,因為它完成了其附帶作用:在使用者瀏覽器是顯示文字。當這個函數的最後一個敘述
語句執行完畢後,PHP接著執行函數呼叫後的下一個敘述語句。
形式參數與實際參數的對比
在前面的例子中,傳遞給函數的參數是「變數」,但並不是必須都如此處理。實際參數(即函數呼叫中的參數)可以是任何能夠評算求值的運算式。在我們的例子中,可以給函數呼叫傳入數字,而不用變數,如下所示:
Print_bettet_deal(1.0,1.59,1.5,2.09);
還要注意,在這個例子中有兩處實際參數變數與形式參數同名的情況(如$price_1還有實際參數與形式參數名稱不同的(如$liters_1與$ amount_1不同)。下一節介紹的內容中會提到兩種方式都沒有問題,函式的形式參數名稱完全獨立存在於函數外部,即使函數呼叫自己也是同樣的。網(www.php.cn)!