S
S
Snewer2015-02-18 21:53:09
PHP
Snewer, 2015-02-18 21:53:09

How to pass arguments to an unknown function?

Hello!
There is a class that loads another class into the $obj property. Further, the __call method from the loaded class can call functions. So far there is this code:

public function __call($function, $args){
    $arg_str = '';
    $count = count($args);
    if($count > 0)   for($i = 0; $i <= $count - 1; $i++)  $arg_str .= '$args['.$i.'],';
    $arg_str = rtrim($arg_str, ',');
    eval('$this->obj->'.$function.'('.$arg_str.');');
  }

is a better solution possible? Thank you.

Answer the question

In order to leave comments, you need to log in

3 answer(s)
A
Alexey Ukolov, 2015-02-18
@Snewer

There are several ways to call a function whose name is in a variable:

// Когда аргументы и их количество известно заранее
// Такой вариант мне кажется самым читабельным
// Оборачивать в фигурные скобки не обязательно
// Я это делаю всегда для того, чтобы было видно, что вызов динамический
$this->obj->{$function}($arg1, $arg2)

or
// Подходит как раз для описанного случая
// Аргументы могут быть любыми и передаются в виде массива
call_user_func_array([$this->obj, $function], [$arg1, $arg2]);

N
Nazar Mokrinsky, 2015-02-19
@nazarpc

Aleksey Ukolov wrote almost like this, here is an analogue of your code without eval (it is almost never needed):

public function __call($function, $args){
    return call_user_func_array([$this->obj, $function], $args);
}

A
Alexander Kubintsev, 2015-02-19
@akubintsev

I don't want to be too boring, but your "magic" has nothing to do with OOP. When referring to your object, you must know exactly what it can do, and using such a __call you initially mean that you are actually using another object that now has a method. And then someone will change it. And you won't know that your object used it implicitly.
It is better to clearly prescribe all proxied methods in your class.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question