Which scenario requires using call_user_func () in php

I do not understand the function call_user_func () in the sense that I understand how it works, but I'm not sure why it is necessary or in what context to use it in php. As far as I know, why not just call a function instead of calling a function with a function? Thnx!

+4
source share
3 answers

I had a couple of situations where it was very necessary. For example, when I created a project that allowed the user to create parts of a programming language, the system had to wrap the definition of a "tag" in a function before running it for security reasons. However, I can’t just call these functions, because I don’t know when I need to call them, or even names. Enter call_user_func () ...

So, I am sure that you are now confused. Let me explain. What my system did was take some XML and convert it to PHP / HTML / JS with PHP. This allowed us to quickly create graphical interfaces (which was the goal). Take this XML, for example:

<window id="login-win" title="Access Restricted" width="310" height="186" layout="accordion" layoutConfig="animate:true"> <panel id="login-panel" title="User Login"> <form id="login-form" title="Credentials"> <textbox id="login-uname" label="Username"/> <password id="login-pass" label="Password"/> <submit text="Login"/> </form> </panel> <panel id="login-register" title="Register"> Nothing, you can't register! </panel> </window> 

Each XML tag will be read, and then the corresponding PHP function is introduced into it. This function will determine what to do for this 1 tag. To remove this, I had files, each of which was named after the tag that it was processing. So, for example, the tag file was "submit.php". The contents of this file will be wrapped in a generated function, for example:

 function tag_submit($variables, $parent, $children){ // deal with the data, then echo what is needed } 

This function name will be stored in an array with the associated tag name with the rest of the generated functions. This ensures that the function is generated once and created only when necessary, saving memory, since I would call if (func_exists ()) to determine if I need it or not.

However, since this is all dynamic, and the user may want to add a new tag, for example, <date>, I needed to use call_user_func () to get the job to work. I cannot hard code a function call if I do not know what the name is.

Hope that all made sense. Basically, yes, this is a rarely used feature, but it is still very useful.

+1
source

call_user_func gives PHP the ability to consider methods and functions as quasi first-class citizens. Functional languages ​​such as javascript do not need these special tools because the function is an object that can be called.

PHP is getting closer to having that concept, though, especially with the closure support that came with PHP5.3. Take a look at the comment I posted by @deceze. There are other tools (namely variable functions , reflection and now closures ) that offer the same basic functionality.

The most remarkable thing about call_user_func is how it allows you to handle global functions, static classes, and objects with a uniform interface. Probably the closest thing they have to one interface is to call functions no matter how they are implemented. Internally, the core PHP development team is working to homogenize a kind of “invoked” or “invokable” interface for the language , I'm sure we will see a clean sentence in PHP5.4 or the next major release.

+2
source

Named functions, anonymous functions, static methods, instance methods, and objects using the __invoke method are collectively called callables. If I have a callable, it can be called by putting the brackets after that "()" (I assume it takes no arguments). This works when our called is stored in a variable, for example:

 $f(); // Call $f 

However, what if I store the called in the property of the object?

 $obj = new stdClass; $obj->my_func = function() {}; $obj->my_func(); // Error: stdClass does not have a "my_func" method 

The problem is that the PHP parser is confused because the code is ambiguous, this may mean invoking a property being called or invoking a method. PHP prefers to always consider this type of code as a method call, so we cannot invoke called properties this way. This is why we need "call_user_func":

 call_user_func($obj->my_func); // Calls $obj->my_func 

There are other cases where PHP does not understand the syntax of ordinary brackets; for example, PHP currently (5.5) does not know how to call the return value of another called:

 get_a_callable()(); // Parse error, unexpected "(" call_user_func(get_a_callable()); // Calls the return value of get_a_callable 

It is also currently not possible to call the definition function directly, which is useful for working with PHP when "let" statements are missing, for example:

 function($x) { echo $x . $x; }('hello'); // Parse error, unexpected "(" call_user_func(function($x) { echo $x . $x; }, 'hello'); // Calls the function 

There are also times when it is useful to have function calls / reified / as the function 'call_user_func'. For example, when using higher-order functions, such as array_map:

 $funcs = [function() { return 'hello'; }, function() { return 'world'; }]; array_map('call_user_func', $funcs); // ['hello', 'world'] 

It is also useful when we do not know how many parameters are required, i.e. we cannot replace our own function ($ f, $ x, $ y, ...) {return $ f ($ x, $ y, ...);} ".

One of the particularly good definitions is a partial application that takes up just a few lines thanks to the calls to_user_func and call_user_func_array:

 function partial() { $args1 = func_get_args(); // $f, $a, $b, $c, ... return function() use ($args1) { // Returns $f($a, $b, $c, ..., $d, $e, $f, ...) $args2 = func_get_args(); // $d, $e, $f, ... return call_user_func_array('call_user_func', array_merge($args1, $args2)); }; } 
0
source

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


All Articles