2011-10-11 123 views
4

當我寫下一個功能是驗證功能的這樣所有參數一個很好的做法:是否需要驗證函數參數?

<?php 
/** 
* foo - Test function 
* 
* @param int $paramA 
* @param str $paramB 
* @param array $paramC 
* 
* @return something 
*/ 
function foo($paramA, $paramB, $paramC) { 
    // verify all parameters 
    if(!is_int($paramA)) { 
     return 0; // or error msg 
    } 
    if(!is_string($paramB)) { 
     return 1; // or error msg 
    } 
    if(!is_array($paramC)) { 
     return 2; // or error msg 
    } 

    // some code in function scope that uses parameters 
    // and saves the results in $result 
    return $result; 
} 

或者我應該依賴於將使用功能和假定他知道他是什麼樣的用戶做和忘記參數驗證?

我個人更喜歡驗證函數的所有參數,並返回代碼的一致性錯誤代碼,並使我的生活更輕鬆。

預先感謝您。

+0

是的,當然這是......一個很好的做法。 **必要**?那麼... –

回答

0

如果它是一個內部函數,只有你會使用,那麼可能沒有驗證每一個單一的參數。如果它是具有取決於用戶輸入的參數的函數(例如,通過$_GET獲得信息,然後將其傳遞給函數),則需要驗證它。

永遠不要依靠用戶或除自己以外的任何人知道他們在做什麼。如果您正在編寫可以稍後重用的代碼(例如,如果您正在編寫自己的框架以便在所有PHP項目中使用),有時候驗證這樣的事情會有幫助。但是,如果它只是一個特定於應用程序的功能,只有你可以用只有你定義的參數調用,我纔不會擔心。

+0

至於你的第二句,第一段:它*是* **必要**總是驗證,清理,轉義,轉換和/或以其他方式*證明*提交的數據是它應該是和沒有「不必要的」內容。 –

+0

當然。爲了清楚起見,我將「應該驗證」改爲「需要驗證」。 –

+0

特別是'$ _GET',不驗證用戶輸入可能會導致一個很大的安全漏洞。 – John

0

爲什麼驗證參數:

  • 有時候我們確實需要對操作有一定的數據類型。如果你給我一個不能代表整數的字符串,並用它來搜索數據庫中的主鍵(通常是一個int),那麼你將遇到麻煩。
  • 它使修復代碼更容易。當您檢查參數時,您可以拋出單個異常並給出非常具有描述性的消息。這樣可以在事件中斷時更輕鬆地修復代碼,因爲您確切知道哪裏出了問題。

的類型檢查的一些技巧:

  • 如果你不知道,is_int是相當錯誤的。我認爲一個有效的檢查是否是一個int是is_numeric($int) && $int==(int)$int
  • 您可以指定對象和數組的類型,如下所示:function foo($paramA, $paramB, array $paramC)
+0

我個人希望在PHP中有一個很好的'assert()'。 –

+0

而且,爲什麼http://fluffykittypics.com沒有用C++編寫,可能有很好的理由。 –

+0

謝謝您的信息,我不知道is_int是錯誤的。 – Starlays

0

真的取決於你對這些參數做什麼的類型嚴格性。

由於PHP是弱類型的,因此您可以通過強制轉換或者讓隱式類型轉換/強制轉換來實現。

如果你只是在每個函數的頭部拋出一堆警戒條件來返回錯誤,那麼它與PHP觸發錯誤本身並沒有多大區別。

+0

如果你只是想在每個函數的頭部拋出一堆警戒條件來返回錯誤,那麼這與PHP觸發錯誤本身並沒有什麼不同。 你是什麼意思? PHP如何觸發我的函數參數錯誤?我很困惑。 謝謝。 – Starlays

+0

你不能依靠自動轉換。你應該做基本檢查。它是否是'1'或'1'並不重要,但如果您期待'1'並獲得''id1'',這將會很重要。 –

2

我想答案是:這取決於

這取決於你是誰編寫代碼。如果你正在尋找的最廣義的答案,然後,你應該。

如果你的腳本將只由你使用,你在你的心中,你總是會正確地使用它的心臟知道,那麼你將(可能),如果你不這樣做是安全的。

如果你的腳本是將被分發到很多很多人的API的一部分,那麼你最肯定要添加錯誤檢查和爲人們提供良好的回落錯誤消息。

如果你是將全部使用相同的代碼一個小團隊的一部分,我還建議,根據您的特定上下文驗證你的論點將是一個不錯的主意。

+0

-1,它不依賴。你檢查這些參數。你每次都檢查它們。你不相信任何人,甚至不相信你自己。 –

+0

@LeviMorrison我不同意你的看法。首先,檢查每個函數中的每個參數肯定會增加代碼長度以及編碼所需的時間。這可能會導致大型項目浪費大量時間。另外,當值通過應用程序時,您將一遍又一遍地檢查相同的參數。過早優化顯然是不好的,但我猜這可能會導致一些性能開銷。 – gilden

+0

@Gilden哦,編碼需要更長的時間,並且可能會給代碼增加一些負擔。當你不檢查你的參數時,在C++中會發生什麼?分割錯誤。當你不檢查你的參數時,PHP會發生什麼?未知的結果。在某些方面,這比seg故障更糟糕。 。 。 –

0

我不同意。我最近偶然發現了一個類似問題(空檢查)an article,但它似乎也適用於php中的類型檢查。我同意作者的觀點。

  • 以使得類型檢查冗餘的方式編寫代碼。
  • 明確地驗證用戶輸入和儘可能快投值到所需的類型。
  • 在某些特殊情況下,您可以並應該使用異常而不是返回一些模糊的錯誤編號。
+0

你的鏈接已經死機 –

+0

謝謝指出,我修好了。 – gilden

0

這是驗證函數參數一個很好的做法。我懷疑你問這個問題,因爲另一方面它會讓你的功能看起來更長,更醜。然而,從NSPL開始args module,這很容易做到。您示例中的功能將爲:

function foo($paramA, $paramB, array $paramC) 
{ 
    expects(int, $paramA); 
    expects(string, $paramB); 

    // do something 
} 

// or type check several arguments 
function sum($x, $y) 
{ 
    expectsAll(numeric, [$x, $y]); 
    return $x + $y; 
} 

更多示例here