六月婷婷综合激情-六月婷婷综合-六月婷婷在线观看-六月婷婷在线-亚洲黄色在线网站-亚洲黄色在线观看网站

明輝手游網中心:是一個免費提供流行視頻軟件教程、在線學習分享的學習平臺!

用 PHP 開發健壯的代碼(3):編寫可重用函數

[摘要]在本系列文章(有關如何在實際情況下開發有效的 PHP 代碼)的第 3 部分中,Amol Hatwar 討論了如何構建最有效的功能型函數,使用這些函數不會犧牲太多性能或可管理性。作者重點闡述了如何編寫...
在本系列文章(有關如何在實際情況下開發有效的 PHP 代碼)的第 3 部分中,Amol Hatwar 討論了如何構建最有效的功能型函數,使用這些函數不會犧牲太多性能或可管理性。作者重點闡述了如何編寫可重用函數,并介紹了如何避免與該任務相關的一些最常見問題。
歡迎回來。在本系列文章的第 1 部分中,我討論了一些基本的 PHP 設計規則,并介紹了如何編寫安全、簡單、與平臺無關且快速的代碼。在第 2 部分中,我介紹了變量,并討論了它們在 PHP 編碼中的用法 — 好的和壞的實踐。

在本文中,您將了解如何在 PHP 中明智地使用函數。在每一種高級編程語言中,程序員都可以定義函數,PHP 也不例外。唯一的區別在于,您不必擔心函數的返回類型。

深入研究
函數可用于:

將幾行代碼封裝成一條語句。

簡化代碼。

最重要的是,將應用程序作為更小的應用程序相互協調的產物。
對于從編譯語言(如 C/C++)轉到 PHP 的開發人員來說,PHP 的性能級別是令人吃驚的。在使用 CPU 和內存資源方面,用戶定義的函數非常昂貴。這主要是因為 PHP 是解釋型和松散類型的。

包裝與否
有些開發人員僅僅因為不喜歡函數的名稱就把他們使用的每個函數都包裝起來,而另一些開發人員卻根本不喜歡使用包裝。

包裝現有的 PHP 函數而不添加或補充現有的功能,是完全不能接受的。除了會增加大小和執行時間外,這樣的重命名函數有時可能會帶來管理上的惡夢。

代碼中的內聯函數會導致莫名其妙的代碼,甚至是更大的管理災難。這樣做的唯一好處可能就是得到一個更快的代碼。

更明智的方法是,僅在需要多次使用代碼,并且對于您希望實現的任務沒有可用的內置 PHP 函數時才定義函數。您可以選擇重命名或僅當需要時才有限制地使用。

圖 1 中的圖表粗略地顯示了可管理性和速度與使用的函數數量之間的相互關系。(在此我沒標明單位,因為數字取決于個體和團隊的能力;這一關系是重要的可視數據。)

圖 1. 可管理性/速度 Vs. 函數數量


命名函數
正如我在本系列文章的第 2 部分(請參閱參考資料)中提到的,要獲得有效的代碼管理,始終都使用公共的命名約定是必不可少的。

其它兩個需要考慮的實踐是:

選擇的名稱應當能很好地提示函數的功能。
使用表明包或模塊的前綴。

假定您有一個名為 user 的模塊,它包含用戶管理函數,那么對于檢查用戶當前是否在線的函數而言,諸如 usr_is_online() 和 usrIsOnline() 這樣的函數名稱都是上佳之選。

將上面的名稱與 is_online_checker() 這樣的函數名稱相比較。得到的結論是,使用動詞優于使用名詞,因為函數始終都會做點什么。

多少參數?
很有可能您將使用已經構造的函數。即使情形并非如此,您可能也希望最大化代碼的使用范圍。要做到這一點,您和其他開發人員應當繼續開發易于使用的函數。沒人喜歡使用那些所帶的參數既晦澀又難于理解的函數,因此請編寫易于使用的函數。

選擇一個能夠說明函數用途的名稱(并減少函數使用的參數數量)是確保易于使用的一個好方法。參數數量的幻數是什么呢?依我看來,超過三個參數就會使函數難以記憶。使用大量參數的復雜函數幾乎都能被拆分成多個更簡單的函數。

沒人喜歡使用湊合的函數。

編寫優質函數
假定您希望在將 HTML 文檔放到瀏覽器之前設置文檔的標題。標題就是 <head>...</head> 標記之間的所有內容。

假定您希望設置 title 和 meta 標記。不使用 setHeader(title, name, value) 函數執行所有工作,而分別使用 setTitle(title) 和 setMeta(name, value) 完成各項工作是一個更佳的解決方案。該方案相互獨立地設置 title 和 meta標記。

進一步考慮,標題可以只包含一個 title 標記,但它可以包含多個 meta 標記。如果需要設置多個 meta 標記,則代碼必須多次調用 setMeta()。在這種情況下,更佳的解決方案是將帶有名稱-值對的兩維數組傳遞給 setMeta(),并且讓函數循環執行該數組 — 同時執行所有操作。

一般來說,象這樣的同時的函數更可取。用函數需要處理的所有數據一次性調用函數,始終優于多次調用函數,并以增量的方式為其提供數據。編寫函數時的主要思想是,盡量減少從其它代碼對其的調用。

據此,setHeader() 解決方案實在不是好方法。顯而易見,我們可以將 setHeader() 重構成 setHeader(title, array),但是也必須考慮到我們失去了相互獨立地設置 title 和 meta 標記的能力。

此外,在實際環境中,標題可能包含多個標記,而不只是 title 和 meta 標記。如果需要添加更多標記,您必須更改 setHeader(),并且改變依賴于它的所有其它代碼。在后一種情形下,只需多編寫一個函數。

下面的等式適用于所有編程語言:


便于記憶的名稱 + 清晰的參數 + 速度和效率 = 在所有編程語言中都適用的優質函數

用分層的方法協調函數
函數很少是獨自存在的。它們與其它函數共同起作用,交換和處理數據以完成任務。編寫可與相同組或模塊中的其它函數良好協作的函數很重要,因為這些函數組或模塊組就是您必須能夠重用的。

讓我們繼續假想的頁面構建示例。這里,該模塊的職責是用 HTML 構建一個頁面。(現在讓我們先略過細節問題和代碼,因為示例的目的只是為了說明:在提高可重用性要素的同時,如何使函數和函數組方便地相互配合。)

從內置的 PHP 函數開始,您可以構建抽象函數,使用它們創建更多處理基本需求的函數,然后依次使用這些函數構建特定于應用程序的函數。圖 2 可以讓您了解其工作原理。

圖 2. 分層的函數


現在,先在內存中構建頁面,然后將完成的頁面分發給瀏覽器。

在內存中構建頁面有兩大好處:

可以用自己的腳本高速緩存已完成的頁面。


如果未能成功構建頁面,可以廢棄完成一半的頁面,并使瀏覽器指向出錯頁面。
現在,您的用戶將不會看到頁面中有錯誤消息的報告了。

根據大多數頁面的結構,需要將頁面構建模塊分成執行以下功能的函數:

繪制頂欄
繪制導航欄
顯示內容
添加腳注
還需要執行下述功能的函數:

高速緩存頁面
檢查頁面是否已經被高速緩存
如果頁面已被高速緩存則顯示它
讓我們稱之為頁面構建器(pagebuilder)模塊。

頁面構建器模塊通過查詢數據庫執行其工作。由于該數據庫是 PHP 之外的,所以將使用數據庫抽象模塊,其職責是為 PHP 中各種不同的特定于供應商的數據庫函數提供同類接口。該模塊中的重要函數有:連接數據庫的函數、查詢數據庫的函數以及提供查詢結果的函數。

假定您還希望實現一個站點范圍的搜索引擎。該模塊將負責搜索站點上與某個關鍵字或某組關鍵字相關的文檔,并根據搜索字符串的相關性或出現該字符串次數最多來顯示結果。如果您還希望記錄搜索以便進行審計,該模塊將與數據庫抽象模塊一起使用。

請記住,您將接受來自用戶的輸入。您需要將其顯示在屏幕上,并廢棄那些看上去懷有惡意的內容。這需要另一個模塊,它負責驗證用戶通過表單提交的數據。

至此,您對我正在講述的概念肯定有了大致的了解。必須將最核心的功能分解成邏輯模塊,要執行它們的任務,應用程序必須使用這些模塊提供的函數。

使用這種分層的方法,簡單的頁面構建呈現應用程序可能如圖 3 所示。

圖 3. 分層的頁面構建應用程序


請注意,在本示例中,核心模塊與處理應用程序的模塊之間沒有層次。也就是說,核心模塊可以從下面的抽象模塊或層中聲明的函數調用和聲明函數,但是應用程序代碼可能不能這樣做。如果應用程序代碼中的函數受任何低層函數“污染”或者封裝了任何低層函數,那么應用程序代碼不應該聲明這些函數。它只能使用低層的函數。這被證實是一個更快的方法。

功能型技術
既然您已經了解了應如何使用和編寫函數,那么就讓我們研究一些常用的技術。

使用引用
簡單點說,引用就象 C 語言中的指針。唯一的區別在于,在 PHP 中,不需要象在 C 語言中那樣使用 * 運算符來解除引用。您可以將它們看成是變量、數組或對象的別名。無論執行什么操作,別名都將影響實際的變量。

清單 1 演示了一個示例。

清單 1. 變量引用
<?php

$name = 'Amol';
$nom = &$name; // $nom is now a reference to $name
$nom .= ' Hatwar';

print("Are you $name?n"); // Jimmy Ray parody?

?>



當將參數傳遞給函數時,函數接收到參數的副本。只要函數一返回,您對參數所做的任何更改都將丟失。如果您希望直接改變參數,這會是一個問題。清單 2 演示了一個說明該問題的示例。

清單 2. 將參數傳遞給函數時的問題
<?php

function half($num)
{
$num = $num / 2;
return $num;
}

$myNum = 15;
$result = half($myNum);

print("The half of $myNum is: $resultn");
print("$myNum contains: $myNumn");

?>




我們希望直接改變 $myNum;通過將 $myNum 的引用傳遞給 half() 函數可以輕易地完成該工作。但是請記住,這并不是個好實踐。使用您代碼的開發人員必須跟蹤所用的引用。這可能會在不經意間導致錯誤蔓延。它還會影響到的函數的易用性。

更好的實踐是直接在函數聲明中使用引用 — 在我們的例子中,使用 half(&$num) 代替 half($num)。這樣,通過記住引用,您就無須記住要將參數傳遞給函數了。

PHP 處理幕后的一些事情。較新的 PHP 版本(從 4.0 起的后續版本)不贊成在調用時按引用傳遞,并且無論如何都會發出警告。(這里有一些建議:如果您正在使用針對早期 PHP 版本編寫的代碼,那么最好更新代碼,而不是通過改變 php.ini 文件來更改 PHP 的行為。)

保留函數調用之間的變量
常常需要維護函數調用之間的變量值。可以使用全局變量,但是變量非常脆弱,并可能被其它函數破壞。我們希望變量對于函數而言是局部變量,并仍然保留其值。

使用 static 關鍵字是一個很好的解決方案。當我希望計算在無法使用調試器的情況下有多少用戶定義的函數被執行時,我常使用這種方法。我只是改變了所有函數(當然是使用自動化的腳本),并在函數體的第一行添加了對執行計數工作的函數的調用。清單 3 描述了該函數。

清單 3. 計數用戶定義的函數
function funcCount()
{
static $count = 0;
return $count++;
}




剛好在腳本完成之前通過調用 funcCount() 來收集變量中的返回值,這種方法是有效的。令人吃驚的是,$count 沒有復位為零;初始化靜態變量的行只執行了一次。

如果您必須訪問函數中的全局變量,那么在使用變量前您需要使用 global 關鍵字。

從 PHP 4 開始還可以這樣做 — 先使用函數,然后再定義它,只要您不會試圖聲明該函數兩次即可。

執行動態調用
在許多情形中,您會發現實際上您并不知道接著必須調用哪個函數。當您在進行事件驅動的編程時,或者當您希望在觸發了系統外的某一事件時調用特定函數時,就會出現這類情形。通過網絡進行通信的腳本就是這種情形的例證。

該方法類似于使用變量名。只要使用外部事件來設置變量,并且使用它作為函數(假定您已經聲明了對應的函數)。有些迷惑嗎?清單 4 做了澄清。

清單 4. 動態函數調用
<?php

function say_hi()
{
print("Hi! ");
}

function say_greeting()
{
print("How are you today?n");
}

function say_bye()
{
print("Enough functions for the day, I hope to see you again next month.n");
print("Till then, have a good timen");
}

// Lets pretend someone just logged in
$my_func = 'say_hi';
$my_func();

// Greet the user
$my_func = 'say_greeting';
$my_func();

// Call it a day
$my_func = 'say_bye';
$my_func();

?>




當您想省事時,也可以使用該方法編寫幾條 switch-case 語句,以評估要使用哪個函數。只需設置變量并使用它作為函數。盡管這里我們故意設置了變量,但是請記住,可以動態完成該工作,而這才顯示了該技術的功能是多么強大。

結束語
在本文中,我們闡述了如何設計和編寫優質函數。我們演示了如何使模塊和腳本集相互配合,以制作更大的應用程序,我們還研究了可以減少編碼工作并生成極佳代碼的技術。

在下一篇文章中,我們將說明 PHP 中的類和對象,以當前的技能為基礎來進行構建,并且仔細研究一些執行高速緩存和數據庫抽象的代碼。

參考資料

在 Developer Shed 的“The Art Of Software Development: Understanding Need”一文中,icarus 著重介紹了應用程序開發周期的第一部分,闡述了在您坐下來編寫第一行代碼前必須做的一些事情。


請閱讀 Developer Shed 上 Harish Kamath 的教程“Using PHP with Java”;該教程包含詳盡的說明性代碼示例,它們已經在帶有 JDK 1.3.0、Apache 1.3.20 和 PHP 4.1.1 的 Linux/i586 上測試過。


Mike Britton 的文章“Scratching the Surface: Getting Started with PHP Fusebox”,完整地介紹了最新的 Fusebox 版本 — 它是一個可伸縮的且有效的 Web 盒樣式的體系架構工具。


PHPGuy 提供了一篇教程“Useful PHP Functions To Build Your PHP Toolkit”,提供了 10 種不尋常的函數,在利用 PHP 編碼的時候,您可以使用這些函數節省時間。


還是出自 PHPGuy 的文章:“Making Sense of Those Cold PHP Errors!”說明了幾種 PHP 錯誤類型,以及如何在開發期間弄清它們的含義。


PHP Debugger 可(免費)用于 PHP 代碼的概要分析和調試。


本系列的第 1 部分“高屋建瓴”(developerWorks,2002 年 8 月)討論了如何為掌握 PHP 打下堅實的基礎。


本系列的第 2 部分“有效地使用變量”(developerWorks,2002 年 9 月)展示了如何通過構造配置文件解析器(使用不同的變量名)使腳本配置變得簡單。


請訪問 dW Linux 專區以獲取更多參考資料。

關于作者
Amol Hatwar 從能記事起就開始接觸計算機。作為 GNU/Linux 的絕對擁護者,他為過去在 Microsoft 平臺上編程感到內疚。他現在作為獨立顧問幫助眾多公司遷移到 GNU/Linux。作為開發 Web 應用程序領域的專家,他把所剩無幾的空余時間花在研究沒人聽說過的技術上。他現在的興趣包括開放源碼軟件、Web 服務、對等計算以及高可用性群集。



主站蜘蛛池模板: 亚洲高清二区 | 亚洲精品在线播放视频 | 日本爽爽爽爽爽爽在线观看免 | 色国产视频 | 在线免费观看h视频 | 色综合久久88| 人成午夜视频 | 视频一区精品 | 亚洲成a人片在线观看88 | 四虎永久免费观看 | 又大又硬又爽免费视频 | 一级特级女人18毛片免费视频 | 人人模人人看 | 伊人手机在线观看 | 色妞网欧美 | 天天曰曰 | 天天干天天操天天玩 | 日本在线视频网站www色下载 | 欧美综合精品一区二区三区 | 日日夜夜精品免费视频 | 亚洲精品老司机 | 日韩不卡手机视频在线观看 | 日日操夜夜操免费视频 | 羞羞爱爱 | 亚洲欧洲一区二区三区在线观看 | 欧美中文字幕一区 | 日韩成人免费aa在线看 | 日韩专区亚洲综合久久 | 天天色姑娘 | 日本亚洲欧美国产ay | 亚洲人成绝费网站色ww | 日韩精品一区二三区中文 | 亚洲欧美一区二区三区不卡 | 天天色播| 天天操天天操天天操 | 人妖女天堂视频在线96 | 午夜久久福利 | 四虎精品福利视频精品 | 中日韩欧美视频 | 天天透天天射 | 在线观看精品视频一区二区 |