2012-03-02 91 views
6

我有一個類:如何在類中使用常量作爲php函數中的參數定義?

class FetchMode 
{ 
const FetchAll = 0; 
const FetchOne = 1; 
const FetchRow = 2;} 

和功能:

function getRecordSet(FetchMode $FetchMode){ some switch cases } 

我想用$ FetchMode作爲開關罩標準,但收到一個錯誤: 捕獲的致命錯誤:參數傳遞給我如何調用一個函數getRecordSet()必須FetchMode的實例,給定整數

是這樣的:

getRecordSet(FetchMode::FetchOne); 

我想提供一個調用函數的可能選項列表。 它可能在PHP?

+0

FetchMode :: FetchOne解析爲1,因此實際上將1傳遞給該函數,而不是FetchMode類型的對象。我不知道你想做什麼,但記住,你必須將一個FetchMode類型的對象傳遞給你的函數,所以你需要某種''fm = new FetchMode();'' – Sgoettschkes 2012-03-02 11:43:11

回答

8

您已經hinted PHP期待的FetchMode一個實例(就像它在錯誤消息說),但FetchMode::FETCH*通過不斷。你必須使用某種Enum實例(我們本來不在PHP中)(噢,有SplEnum但是誰使用它?))或者改變方法簽名來排除typehint。然而,代替開關/箱,您可以使用solve this more easily via PolymorphismStrategy pattern,例如solve this more easily via PolymorphismStrategy pattern。而不是做類似

public function getRecordSet($mode) 
{ 
    switch ($mode) { 
     case FetchMode::ALL: 
      // code to do a fetchAll 
      break; 
     case FetchMode::ONE: 
      // code to do a fetchOne 
      break; 
     default: 
    } 
} 

這將增加你的等級和力量改變這個類,每當你需要添加額外的FetchModes的Cylcomatic ComplexityFetchMode,你可以這樣做:

public function getRecordSet(FetchMode $fetchModeStrategy) 
{ 
    return $fetchModeStrategy->fetch(); 
} 

,然後讓一個interfaceprotect the variation

interface FetchMode 
{ 
    public function fetch(); 
} 

,並添加具體FetchMode類每個ES支持FetchMode

class FetchOne implements FetchMode 
{ 
    public function fetch() 
    { 
     // code to fetchOne 
    } 
} 
class FetchAll … 
class FetchRow … 

這樣,你永遠不會有再次觸摸類與getRecordSet方法,因爲它會爲實現該FetchMode inteface任何類的工作。所以,無論何時你有新的FetchModes,你只需添加一個新的類,從長遠來看,這個類更易於維護。

0

我不知道你的

would like to offer a list of possible choices in calling a function. Is it possible in php?

但對於錯誤部分的意思:假設你有一個變種,例如$foo。當你做echo $foo時,你不會得到var的名字,但它的值。這是因爲一個var有一個名字並且指向一個值。每次訪問var基本上都會返回它指向的值。它與常量相同;你把常數名稱放在那裏,但基本上你是指向你的存儲值。這意味着getRecordSet(FetchMode::FetchOne);getRecordSet(1);是一樣的。

因此,getRecordSet(FetchMode $FetchMode)增加了must be an instance of FetchMode,因爲FetchMode::FetchOne指向一個整數。

要解決此問題,您需要使用getRecordSet(int $FetchMode)

+0

我不'不想強迫其他開發者知道哪個選擇具有哪個價值。這就是爲什麼我試圖使用函數名(FetchMode :: FetchOne),而不是函數名(1) – dllhell 2012-03-02 11:51:03

+1

他們不必知道。你仍然可以使用'FetchMode :: FetchOne',但是你的函數聲明仍然需要一個'int'而不是'FetchMode'作爲參數(因爲你的參數指向一個'int'而不是'FetchMode'的一個實例),除非Gordon在他的回答中解釋說,你正在使用一些戰略模式。 – pduersteler 2012-03-02 11:54:33

相關問題