Take the 2-minute tour ×

I want to trigger a function based on a variable.

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

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

The * line is the line that's not correct.

I've done this before, but I can't find it. I'm aware of the potential security problems, etc.

Anyone? Many thanks.

share|improve this question
add comment

4 Answers

up vote 14 down vote accepted

You can do that, but not without interpolating the string first:

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

Or, skip the temporary variable with call_user_func():

call_user_func('sound_' . $animal);
share|improve this answer
Thanks a bunch. You saved me a lot of irritation! –  LibraryThingTim Nov 22 '09 at 4:40
This is an intriguing method. Is it a security risk to give a REQUEST variable direct access to this? If so, what measures can be taken to prevent it? Perhaps a list of functions that you only want to give access to, and a check against this list when the REQUEST var of this name is encountered? –  SSH This Dec 18 '12 at 1:33
You should not give REQUEST direct access (read: ALWAYS sanitize user input). A dispatch table along the lines of Greg Hewgill's answer is probably the best solution. You can check validity of the REQUEST input via array_key_exists(), just make sure you quote the values (sound_dog -> 'sound_dog') or it'll throw a notice. –  scribble Dec 20 '12 at 20:39
add comment


To do your example, you'd do

$animal_function = "sound_$animal";
share|improve this answer
add comment

You should ask yourself why you need to be doing this, perhaps you need to refactor your code to something like the following:

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

$animal = "cow";
print animal_sound($animal);
share|improve this answer
I find your method much less clean. This is the C mindset. –  San Jacinto Nov 22 '09 at 4:41
1 function that does the same thing as 2 functions? –  Sam152 Nov 22 '09 at 4:42
C mindset? Using a hash table? More like the maintainable code mindset. –  recursive Nov 22 '09 at 4:43
99% of the time, you'd be right. This is in a virtual <i>sea</i> of code, and I can only remember doing it once before. Where it comes in handy, however, is when you have a whole bunch of very similar functions, like: search_book_amazon(); search_book_bn(); search_book_z3950(); ... 20 more In cases like that... <pre>if($type == 'amazon') { search_book_amazon(); } if(type == 'bn') { search_book_bn(): }</pre> just adds another point of failure, and is annoying to type to boot. –  LibraryThingTim Nov 22 '09 at 4:45
I wish my PREs worked in comments. What, when we comment we can't use code?! –  LibraryThingTim Nov 22 '09 at 4:45
show 5 more comments

You can do it like this:

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

However, a much better way would be to use an array:

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

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

One of the advantages of the array method is that when you come back to your code six months later and wonder "gee, where is this sound_cow function used?" you can answer that question with a simple text search instead of having to follow all the logic that creates variable function names on the fly.

share|improve this answer
add comment

Your Answer


