25

I'd like to iterate over an array and dynamically create functions based on each item. My pseudocode:

$array = array('one', 'two', 'three');

foreach ($array as $item) {
    public function $item() {
        return 'Test'.$item;
    }
}

How should I go about doing this?

4
  • 4
    Can i ask why you want to create this functions Commented Oct 12, 2012 at 22:41
  • Adding too much dynamic can make a program unreadable - which is equivalent to unmaintainable. Can you go into details of what you have and what you want to get? Commented Oct 13, 2012 at 0:46
  • 1
    possible duplicate of Dynamically Create Instance Method in PHP Commented May 29, 2015 at 10:03
  • 1
    @Baba and Sven Simple, he is asking a good point because some functions seems to be same with only difference of one word. We are duplicating the code. So best way is write a dynamic code. Commented Nov 28, 2017 at 10:17

2 Answers 2

34

Instead of "creating" functions, you can use the magic method __call(), so that when you call a "non-existent" function, you can handle it and do the right action.

Something like this:

class MyClass{
    private $array = array('one', 'two', 'three');

    function __call($func, $params){
        if(in_array($func, $this->array)){
            return 'Test'.$func;
        }
    }
}

Then you can call:

$a = new MyClass;
$a->one(); // Testone
$a->four(); // null

DEMO: http://ideone.com/73mSh

EDIT: If you are using PHP 5.3+, you actually can do what you are trying to do in your question!

class MyClass{
    private $array = array('one', 'two', 'three');

    function __construct(){
        foreach ($this->array as $item) {
            $this->$item = function() use($item){
                return 'Test'.$item;
            };
        }
    }
}

This does work, except that you can't call $a->one() directly, you need to save it as a variable.

$a = new MyClass;
$x = $a->one;
$x() // Testone

DEMO: http://codepad.viper-7.com/ayGsTu

Sign up to request clarification or add additional context in comments.

3 Comments

@NullUserException: Thanks for adding the fact that __call() is a "magic method".
You can also use the magic __get() function to call closures / callbacks functions then:, see Dynamically Create Instance Method in PHP - If you really think __call() or __get() is what has been asked for, please suggest an existing question as a duplicate.
How can you PHP docblock this so editor does not warn about "non existing functions"?
4
class MethodTest
{
    private $_methods = array();

    public function __call($name, $arguments)
    {
        if (array_key_exists($name, $this->_methods)) {
            $this->_methods[$name]($arguments);
        }
        else
        {
            $this->_methods[$name] = $arguments[0];
        }
    }
}

$obj = new MethodTest;

$array = array('one', 'two', 'three');

foreach ($array as $item) 
{
    // Dynamic creation
    $obj->$item((function ($a){ echo "Test: ".$a[0]."\n"; }));
    // Calling
    $obj->$item($item);
}

The above example will output:

Test: one
Test: two
Test: three

2 Comments

is there a way to get around the $a[0] and to just have $a ?
@duck class MethodTest { public function __call($name, $arguments) { echo "" . "Method: ".$name."\n" . (!empty($arguments) ? "Parameters: ". implode(', ', $arguments) : "No parameter!"). "\n"; } } $obj = new MethodTest; $obj->ExecTest('par 1', 'par 2', 'others ...'); $obj->ExecTest();

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.