2009-11-22 84 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 2009-11-22 04:40:51

+0

这是一个有趣的方法。给REQUEST变量直接访问它会带来安全风险吗?如果是这样,可以采取什么措施来预防呢?也许是你只想访问的函数列表,并且在遇到这个名字的REQUEST var时检查这个列表? – 2012-12-18 01:33:03

+0

您不应直接访问REQUEST(请阅读:始终清理用户输入)。根据Greg Hewgill的回答,派送表可能是最好的解决方案。您可以通过array_key_exists()检查REQUEST输入的有效性,只要确保引用值(sound_dog - >'sound_dog')或它会发出通知。 – scribble 2012-12-20 20:39:39

1

你应该问自己,为什么你需要做这个,也许你需要重构你的代码类似如下:

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

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

我发现你的方法不够干净。这是C的心态。 – 2009-11-22 04:41:36

+0

1个功能和2个功能一样吗? – Sam152 2009-11-22 04:42:27

+4

C心态?使用散列表?更像可维护的代码思维。 – recursive 2009-11-22 04:43:38

15

你可以这样说:

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

然而,一个更好的方法是使用一个数组:

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

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

之一阵列方法的优点是,当你回到你的代码6几个月后,不知道“哎呀,这个sound_cow函数用在哪里?”你可以通过简单的文本搜索来回答这个问题,而不必遵循所有创建可变函数名称的逻辑。

0

对于课程功能,您可以使用$this->self::。下面的示例提供了一个函数输入参数。

$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