2009-11-22 9 views
14

変数に基づいて関数をトリガーしたい。PHP:関数名の変数

function sound_dog() { return 'woof'; } 
function sound_cow() { return 'moo'; } 

$animal = 'cow'; 
print sound_{$animal}(); *

*行が正しくない行です。

私は以前これをしていましたが、見つけられませんでした。セキュリティ上の問題などが考えられます。

誰でもがいいですか?どうもありがとう。

答えて

19

にしてください:

$animfunc = 'sound_' . $animal; 
print $animfunc(); 

か、一時的にスキップ変数:call_user_func()

call_user_func('sound_' . $animal); 
+0

ありがとうございました。あなたは私に多くの刺激を救った! – LibraryThingTim

+0

これは興味深い方法です。 REQUEST変数に直接アクセスできるようにするのはセキュリティリスクですか?もしそうなら、それを防ぐためにどのような措置を講じることができますか?おそらくあなたがアクセス権を与えたい機能のリストと、この名前のREQUEST変数に遭遇したときにこのリストをチェックしますか? –

+0

あなたはREQUESTに直接アクセスするべきではありません(読んでください:常にユーザ入力を消毒してください)。 Greg Hewgillの答えに沿ったディスパッチテーブルがおそらく最適な解決策です。あなたはarray_key_exists()を介してREQUEST入力の有効性をチェックすることができます。値(sound_dog - > 'sound_dog')を引用することを忘れないでください。 – scribble

1

あなたがこれをやってする必要がある理由あなたはおそらく、あなたは次のようにコードをリファクタリングする必要があり、自分自身に問う必要があります。

function animal_sound($type){ 
    $animals=array(); 
    $animals['dog'] = "woof"; 
    $animals['cow'] = "moo"; 
    return $animals[$type]; 
} 

$animal = "cow"; 
print animal_sound($animal); 
+1

あなたの方法ははるかにクリーンであるとわかりました。これはCの考え方です。 –

+0

2つの関数と同じことをする1つの関数? – Sam152

+4

Cの考え方?ハッシュテーブルを使用していますか?メンテナンス可能なコードの考え方によく似ています。 – recursive

15

あなたはこのようにそれを行うことができます。しかし

$animal = 'cow'; 
$sounder = "sound_$animal"; 
print ${sounder}(); 

、はるかに優れた方法のアレイを使用することです:あなたが戻ってあなたのコード6に来たときに、配列方法の利点の

$sounds = array('dog' => sound_dog, 'cow' => sound_cow); 

$animal = 'cow'; 
print $sounds[$animal](); 

一つは、ということです数ヶ月後に "ええ、これはsound_cow関数が使われていますか?"その場で可変関数名を作成するすべてのロジックに従わなくても、簡単なテキスト検索でその質問に答えることができます。

0

クラス機能に$this->self::を使用できます。関数input-parameterを使用して以下に示す例。

$var = 'some_class_function'; 
call_user_func(array($this, $var), $inputValue); 
// equivalent to: $this->some_class_function($inputValue); 
0

ファンクション名を作成するには、中括弧を使用できます。下位互換性は確かではありませんが、少なくともPHP 7以上で対応できます。 (「追加」または「サブ」の)ユーザー選択したタイプに基づいて時間を加算または減算するためにカーボンを使用した場合ここで

は私のコードです:

$type = $this->date->calculation_type; // 'add' or 'sub' 

$result = $this->contactFields[$this->date->{'base_date_field'}] 
        ->{$type.'Years'}($this->date->{'calculation_years'}) 
        ->{$type.'Months'}($this->date->{'calculation_months'}) 
        ->{$type.'Weeks'}($this->date->{'calculation_weeks'}) 
        ->{$type.'Days'}($this->date->{'calculation_days'}); 

ここで重要な部分は{$type.'someString'}セクションです。これにより、実行前に関数名が生成されます。したがって、最初のケースでは、ユーザーが「追加」を選択した場合、{$type.'Years'}addYearsになります。