1

Is it possible to have dynamic function calls in PHP? I don't know if I am calling it the right name, but my example hopefully will explain what I want.

<?
    function image_filename(){
        global $the_image;
        return return $the_image->filename;
    }
    function image_anchor(){
        global $the_image;
        return getAnchor($the_image->id);
    }
    // is there a way to make a function that will do something like this:
    // I know it's possible using a class and __call, but is it possible for a general case
    function image_REQUEST(){
        global $the_image;
        $args = func_get_args();
        switch(REQUEST){
            case "filename":
                return $the_image->filename;
            break;
            case "anchor":
                return getAnchor($the_image->id);
            break;
        }
    }
?>

Clarification:

I know about variable functions, and call_user_func. These are not what I am looking for. Basically, I don't want to define image_filename or image_anchor, but have them defined when they are called.

Jason
  • 3,357
  • 1
  • 22
  • 29
  • There is `call_user_func()`, `call_user_func_array()`, and [variable functions](http://stackoverflow.com/questions/3645361/variable-variables-in-php/3645367#3645367). – BoltClock Dec 29 '10 at 18:29
  • this might help http://stackoverflow.com/questions/4218123/dynamic-function-call-php – Rami Dabain Dec 29 '10 at 18:30
  • @BoltClock - correct, but I still have to define the functions individually. While I can do that, I am just interested in making a dynamic function set. – Jason Dec 29 '10 at 18:30
  • 1
    What's wrong with passing something like `$request` as a parameter? – BoltClock Dec 29 '10 at 18:31
  • Some functions want different args. Besides, I am just interested. – Jason Dec 29 '10 at 18:34

8 Answers8

3

There is no way to define "magic" or "dynamic" functions (like with __call) for functions not defined within a class. You can however call functions dynamically. There are several ways to do this- I would recommend call_user_func_array() function, which lets you call a function, passing its arguments as an array.

For example:

$type = 'filename';
call_user_func_array("image_$type", $args);

For more info, see http://php.net/manual/en/function.call-user-func-array.php

mfonda
  • 7,873
  • 1
  • 26
  • 30
1

You mean variable functions?

<?php

function user_func($x) { echo $x; }

$x = "user_func";
$x(1);

?>

http://php.net/manual/en/functions.variable-functions.php

To dynamically create functions, use create_function (http://ca3.php.net/create-function):

<?php
$func = create_function('$x', 'echo $x;');
$func(1);

?>

You can store them in arrays:

<?php
$funcs = array();
$funcs['error'] = create_function('$x', 'echo $x;');
?>
Ming-Tang
  • 17,410
  • 8
  • 38
  • 76
0

Yes.

But don't. unless you like having future programmers hunt you down and gut you on the sidewalk.

DampeS8N
  • 3,621
  • 17
  • 20
  • Embedding multiple functions into one function is duplicating the idea behind objects, only in a totally non-standard way. It is confusing. And the end result is going to be one MAJORLY unhappy maintainer. After wasting hours hunting the problem down, possibly days. – DampeS8N Dec 29 '10 at 18:33
  • phooy. I do declare redundant function using `eval()`. Is that bad, too? – Jason Dec 29 '10 at 18:39
  • LOL - it won't let me just say LOL – DampeS8N Dec 29 '10 at 18:44
  • @DampeS8N - You didn't answer the question, is that bad? Though judging by your original answer, it is *yes*... – Jason Dec 29 '10 at 18:49
  • I hope SOOO much that you are joking – DampeS8N Dec 29 '10 at 18:55
  • @DampeS8N - What is the point of your statement? He's not doing OOP so who cares if he's duplicating OOP functionality? On top of that, people can make the same spaghetti code mistakes in OOP as well. More than once I have had to debug a "God" class over several thousand lines long. Personally, code like this can elegantly solve strategy pattern implementations which is one of the best architecture patterns out there. – Matthew Purdon Dec 29 '10 at 19:03
  • @DampeS8N - haha... I don't claim to know "coding ethics." This is just something I am doing for fun. – Jason Dec 29 '10 at 19:04
  • @Matthew Purdon - it is true. There are about 15 functions that I create using `eval()` (though I will change to `create_function` upon another request). I personally think 5 lines of code is easier to debug than 75. – Jason Dec 29 '10 at 19:07
0

Use something like:

$image_request = 'image_' + REQUEST;
echo $image_request();
// lets say REQUEST = filename, then above will echo the result of function: image_filename();

These are known as variable functions, and the basic is that you store the function's name in a variable, lets say $var, and then call the function using: $var().

Also, as you state in your comment to BoltClock, if you are interested in a kind of a dynamic function set, why not use something like this:

function image_functions(REQUEST) {
    switch (REQUEST) {
    // ...
    }
}
Stoic
  • 10,536
  • 6
  • 41
  • 60
  • I use variable functions. I edited the question the clarify. I can't pass `REQUEST` in what I am using them for. In my example, it's possible, but for what I am actually doing, it's not. – Jason Dec 29 '10 at 18:38
  • If you can switch `REQUEST`, I can not understand why you cant pass REQUEST to the function calls.. or you want something that goes like e.g. someway you request an arbitrary function `image_arbit`, the `REQUEST` parameter is created from this, which you then switch?? I guess it can still be done by splitting the function name from the call, getting the `REQUEST` parameter as a separate variable and then following any of the suggested methods here? – Stoic Dec 29 '10 at 18:42
  • 1
    because the specific functions have variable `args` and I traverse through the arguments, if I pass another argument it would traverse to the wrong place. I would give a better example, but my question was already answered: *no, it's not possible* (though I already kind of knew the answer). – Jason Dec 29 '10 at 18:48
0

Is this what you are looking for ?

function foo() {
// code ...
}

$functionName = "foo";

$functionName();
Jonas Schmid
  • 5,360
  • 6
  • 38
  • 60
  • No, I still have to define the function `foo()` individually. I am looking to not define the functions, but dynamically define them. – Jason Dec 29 '10 at 18:33
0

http://php.net/manual/en/function.call-user-func.php

<?php
function increment(&$var)
{
    $var++;
}

function decrement(&$var)
{
    $var--;
}

$a = 5;
$func = "increment";
call_user_func($func, $a);
echo $a."\n";

$func = "decrement";
call_user_func($func, $a);
call_user_func($func, $a);
echo $a."\n";;
?>

produces

6
4
Andrew Sledge
  • 10,163
  • 2
  • 29
  • 30
0

You can also do simple string replacements.

<?php
$action = $_REQUEST['action'];
$functionName = 'image_' . $action;
if (function_exists($functionName)) {
    $functionName($the_image);
} else {
  echo "That function is not available";
}

And that's about it. I added the extra error checking so that you don't try to run functions that don't exist.

Matthew Purdon
  • 754
  • 11
  • 28
0

I don't understand why you don't just make REQUEST a parameter but you can define functions inside an eval() call.

function makeFunction($name)
{
    $functionName = "process_{$name}";

    eval("
        function {$functionName}() {
            echo \"Hi, this is {$functionName}.\\n\";
        }
    ");
}

makeFunction("Hello");

process_Hello();

Good luck with the escapes.

aib
  • 45,516
  • 10
  • 73
  • 79