2012-03-02 8 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に解決されるため、実際にはFetchMode型のオブジェクトではなく1に関数を渡します。私はあなたが何をしたいのか分からないが、FetchMode型のオブジェクトをあなたの関数に渡さなければならないということを心に留めておいて、ある種の '' $ fm = new FetchMode(); '' – Sgoettschkes

答えて

8

あなたは(それがエラーメッセージで述べているだけのように)FetchModeのインスタンスを期待するhinted PHPをしましたが、一定のFetchMode::FETCH*渡します。あなたは何らかの種類のEnumインスタンスを使用する必要があります(これはPHPでネイティブではありません)(SplEnumがありますが、誰がそれを使用しますか?))、または型シグネチャを変更して型ヒントを除外します。

ただし、スイッチ/ケースの代わりに、solve this more easily via PolymorphismStrategy patternとすることができます。その後、

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

とがあります。代わりに

クラスの Cylcomatic Complexityを高め、あなたは追加のFetchModesを追加する必要があるとき、そのクラスへの変更と FetchModeを強制的に、あなたが行うことができます
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: 
    } 
} 

ような何かを行いますprotect the variation

interface FetchMode 
{ 
    public function fetch(); 
} 

とコンクリートFetchModeクラスを追加するinterfaceそれぞれのESはFetchMode

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

この方法をサポートし、あなたはそれがそのFetchMode intefaceをを実装する任意のクラスのために動作しますので、再びそのgetRecordSetメソッドを持つクラスをタッチする必要はありませんよ。新しいFetchModeがあるときはいつでも、新しいクラスを追加するだけです。これは長期的にはもっとメンテナンスが容易です。

0

私はあなたが

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

ではなく、エラー部分のために何を意味するのか分からない:あなたはVARを持って、例えば想像します$fooecho $fooを実行すると、varの名前は取得されませんが、その値は取得されません。これは、varが名前を持ち、値を指しているからです。 varへのアクセスはすべて、基本的にそれが指す値を返します。それは定数と同じです。あなたはそこに定数の名前を入れますが、基本的にあなたの記憶された価値を指しています。つまり、getRecordSet(FetchMode::FetchOne);getRecordSet(1);は同じです。

getRecordSet(FetchMode $FetchMode)は、FetchMode::FetchOneが整数を指しているため、must be an instance of FetchModeを発生させます。

これを修正するには、getRecordSet(int $FetchMode)を使用する必要があります。

+0

I don '他の開発者にどちらの選択肢がどの価値を持っているかを知りたい。だから私はfunctionname(1) – dllhell

+1

の代わりにfunctionname(FetchMode :: FetchOne)を使用しようとしているのです。あなたはまだ 'FetchMode :: FetchOne'を使うことができますが、あなたの関数宣言は引数として' FetchMode'ではなく、 'int'を指します(あなたの引数が' FetchMode'のインスタンスではなく 'int'を指しているので)ゴードンが答えで説明したように、あなたはいくつかの戦略パターンを使用しています。 – pduersteler

関連する問題