Calling a variable function using a class property as the name of the function

The following code uses the string "rand" stored in the $ prop property to call the rand () function as a variable, using $ function as a temporary local variable.

class C { private $prop = "rand"; public function execute() { $function = $this->prop; echo $function(); } } $c = new C(); $c->execute(); 

This works, but I need to call the variable function stored in $ this-> prop, using only one operator and avoiding the temporary variable.

I'm out of luck with

 echo $this->prop(); 

because it actually calls the prop () method, which does not exist, and in any case, this is not what I want to do.

Since $ this-> prop is actually a string, I tried the following, but it causes a syntax error:

 echo ($this->prop)(); 

I also tried

 echo call_user_func($this->prop); 

Although he does this work, this is not an option for me, because it is not a variable function.

It appears that function variables only work using local variables as the name of the function.

Does anyone know a way to directly call a variable function using the class property as the function name, avoiding the local temporary variable and using call_user_func ()?

Edit: I understand your perplexity, so I'm going to explain what's wrong with call_user_func.

I am just exploring the possibilities offered by variable functions, which are apparently smaller than those offered by variable variables.

Try using variable variables, which are its simplest form.

Suppose we have a function f () that returns the string "something"

 function f() { return "something"; } 

then a class property containing the string "something"

 $this->prop = "something"; 

$ something is a local variable

 $something = "I am a local variable"; 

Then all the following statements will be executed:

 $r = ${"something"}; $r = ${$this->prop}; $r = ${f()}; 

My personal conclusion: no matter how the string "something" is received; just surround it with curly braces {} and add the dollar symbol $ to count it as a variable. Pretty flessibe.

Let's try the same for variable functions

Now we have a function f () that returns the string "rand"

 function f() { return "rand"; } 

then a class property containing the string "rand"

 $this->prop = "rand"; 

Function variables, on the other hand, do not allow you to read a string followed by a bracket () as a function call.

 $r = "rand"(); // Produces a syntax error, unexpected '()' after a string $r = $this->prop(); // Calls the 'prop()' method, which does not exist $r = f()(); // Again a syntax error, unexpected '()' after the function f() 

I must conclude that for a variable's functions , a local variable is always required : (

+6
source share
3 answers

You need to implement the magic __call method, for example:

 class C { private $prop = "execute"; public function __call($method, $args) { if($method == "prop") // just for this prop name { if(method_exists($this, $this->prop)) return call_user_func_array([$this, $this->prop], $args); } } public function execute ($s){ echo '>>'.$s.'<<'; } } $c = new C; $c->prop(123); 
+2
source

This certainly looks like a blatant omission in the PHP syntax. (Although taken literally, I think they are function variables, not property functions !?) I might have expected the following curly bracket syntax to work, but it isn’t, Parse error: syntax error, unexpected '{' in ...

 echo {$this->prop}(); 

However, there are significant advantages to using the syntax of variable functions over other methods. Variable functions execute faster than call_user_func() / call_user_func_array() and initially support a backlink, rather than the "random" default call time with call_user_func_array() (which is deprecated in all other cases).

An alternative to the __call magic method (above), which will be relatively slow, is simply to use the wrapper method with which you pass the name of the function / method and use the function variables inside that wrapper method.

In its simplest form:

 function callUserFunc($callable) { return $callable(); } 

Due to performance advantages (using call_user_func_array() ), several frameworks implement a similar helper method that allows a variable number of arguments. This other question / answer goes deeper and covers some performance benchmarks: A function call with explicit parameters compared to call_user_func_array ()

+2
source

In case someone asks a question, since PHP 7 we get called functional expressions.

While this particular case is undocumented, it actually works in the following example:

 class Test { private $func = "strtolower"; public function testFunc() { return ($this->func)("ALPHABET"); } } $t = new Test(); echo $t->testFunc(); //echoes alphabet in PHP 7+ error in anything below 

This can be seen at https://3v4l.org/JiuIF

0
source

Source: https://habr.com/ru/post/981460/


All Articles