首頁 >後端開發 >php教程 >PHP一種友善的函數傳參模式設計

PHP一種友善的函數傳參模式設計

WBOY
WBOY原創
2016-07-25 08:46:181005瀏覽

PHP一種友善的函數傳參模式設計,有需要的朋友可以參考下。


當一個類別的建構函式函數中,需要傳入的參數較多時,程式設計師在編碼時由於傳入的順序和寫法難記憶,容易出現編譯錯誤,或是出現值傳給錯誤參數(弱型別語言)的情況.


友善的功能設計

程式設計師在實例化一個class時,傳入的參數應該滿足以下 友善目標:
1. 能夠只傳入部分參數
2. 能夠不依序傳入參數
3. 能夠不區分參數的大小寫
4. 能夠及時準確的提示傳參時產生的錯誤


改進流程 例1-在成員變數中賦預設值 請看以下程式碼,函數的預設值在成員變數中賦予,這樣在只傳入部分參數時,系統會產生notice,即不滿足"友善目標"中的第一條.
  1. class FileUpload
  2. {
  3. private $filepath; //指定檔案儲存的路徑
  4. private $allowtype = array("gif", "jpg" ", "jpeg", "png"); //允許的類型
  5. private $maxsize = 1000000; //允許上傳的檔案大小1M
  6. private $israndname = true; //是否重新命名檔案
  7. function __construct($filepath, $allowtype, $maxsize, $israndname)
  8. {
  9. $this->filepath = $filepath;
  10. $this->allowtype = $allowtype;
  11. $this->maxsize = $maxsize;
  12. $this->israndname = $israndname;
  13. var_dump($this);
  14. }
}n複製程式碼

例2-在建構函式中賦預設值

這次,為了消除上例的notice,實作可以傳入任意數量的參數,沒有傳入的參數使用預設值,將程式改為:在建構函式中設定預設值.

又一個問題出現:當程式設計師傳入參數為(“/upload”,array(“jpg”,”gif”),false)時,即程式設計師忘記傳入了maxsize參數,這時系統會錯誤的將false賦值給maxsize而不是israndname,系統沒有任何錯誤輸出,為後續工作留下隱患!
  1. class FileUpload
  2. {
  3. private $filepath;
  4. private $allowtype;
  5. private $maxsize; 🎜>
  6. function __construct(
  7. $filepath = "/upload",
  8. $allowtype = array("gif", "jpg", "jpeg", "png"),
  9. $maxsize = 1000000,
  10. $israndname = true)
  11. {
  12. $this->filepath = $filepath;
  13. $this->allowtype = $allowtype;
  14. $this->maxsize = $maxsize;
  15. $this->israndname = $israndname;
  16. var_dump($this);
  17. }
複製代碼 例3-使用陣列封裝參數
為解決例2的問題,我們可以對傳入的值進行檢查來防止賦值錯位的情況發生(反正一般情況下我們都會對傳入的值進行檢查).然而這並不是解決問題的方法,因為我們要實現的功能還有使程式設計師可以不按順序傳值.

在弱型別語言中,解決這個問題可以使用 數組 的特殊性,將所有傳遞的參數封裝到數組中,以key=>value鍵值對的形式保存.請看如下碼:

    class FileUpload
  1. {
  2. private $filepath;
  3. private $allowtype;
  4. private $maxsize; 🎜>
  5. function __construct($options=array([預設值]))
  6. {
  7. //解析傳入的陣列
  8. foreach($options as $key=>$value){
  9. $this->$key = $value;
  10. }
  11. }
  12. 複製程式碼
這樣就解決了傳入參數的順序問題,同時也解決了只傳部分參數的問題.
然而新的問題出現了,這時程式設計師需要輸入一個陣列作為參數,如下:

$up = new $FileUpload(array(
"filepath" => "/upload",
    "israndname" => false,
  1. "maxsize" => 2000000
  2. ));
  3. 複製程式碼
例4-解決參數的大小寫 在使用陣列封裝參數之後,這時需要程式設計師手動輸入變數的名字,這就會因為風格不同導致MaxSize, maxSize, maxsize 這樣的寫法問題,解決這個問題只需要在宣告成員變數時都統一用小寫,然後在建構子裡加一行:

foreach($options as $key=>$value){
$key = strtolower($key);
  1. ...
  2. }
  3. 複製程式碼

到這裡,我們的設計已經滿足了 友善目標 中的前三點,整體程式碼如下:

  1. class FileUpload {
  2. private $filepath;
  3. private $allowtype;
  4. private $maxsize
  5. privateis; 🎜> "$filepath" => "./",
  6. "$allowtype" => array("txt","jpg"),
  7. "$maxsize " => 1000000,
  8. "$israndname" => true
  9. )){
  10. //解析傳入的陣列
  11. foreach($options as $key=>$value){
  12. $key = strtolower($key);
  13. $this->$key = $value;
  14. }
  15. }
  16. }
  17. 複製代碼
例5-處理傳入key的錯誤 在上例中,如果程式設計師傳入了一個類別中根本沒有的參數,系統會報錯,這裡我們有兩種處理方案: 1. 忽略無效參數,僅執行有效參數
2. 友善的提示出你傳入的某個參數無效


個人認為為了程式的健全性,不能輕易容許錯誤的程式碼存在,故選擇第二者,我們將這個錯誤友善的提示給呼叫者.

foreach($options as $key=>$value){
$key = strtolower($key);
    //判斷類別中是否有這個變數
  1. if(in_array($key, get_class_vars(get_class($this)))) {
  2. $this->$key = $value;
  3. }else{ //提示錯誤位置與參數
  4. echo "Error when init class ".get_class($this)." with key: ".$key." in array !";
  5. exit;
  6. }
  7. }
  8. 複製程式碼
例6-檢查傳入value是否合法 至此,預期的4個目標均已實現,且為了使__construct()函數具有復用性,使用時可以直接paste,我們將對value的檢查抽象化成一個函數,請看修改後的程式碼:

class FileUpload {
    //變數名稱皆使用小寫
  1. private $filepath;
  2. private $allowtype; private $size; 🎜> private $israndname;
  3. //在建構子中賦予預設值
  4. function __construct($options=array(
  5. "$filepath" => "./",
  6. " $allowtype" => array("txt","jpg"),
  7. "$maxsize" => 1000000,
  8. "$israndname" => true
  9. )){
  10. //解析傳入的陣列
  11. foreach($options as $key=>$value){
  12. $key = strtolower($key);
  13. //判斷key是否在類別中宣告
  14. if(in_array( $key, get_class_vars(get_class($this)))) {
  15. //檢查value是否符合要求
  16. if(checkValue($key,$value)) {
  17. $this->$key = $ value;
  18. } else {
  19. //提示錯誤位置與參數
  20. echo "Invalid value".$value."found when init class ".get_class($this)." with key: ".$ key." in array !";
  21. exit;
  22. }
  23. }else{
  24. //提示錯誤位置與參數
  25. echo "Error when init class ".get_class($this). " with key: ".$key." in array !";
  26. exit;
  27. }
  28. }
  29. }
  30. function checkValue{
  31. if(){
  32. ...
  33. return true;
  34. }
  35. return false;
  36. }
  37. }
  38. 複製代碼
PHP
陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn