How can the WP function add_action receive another function as its argument? I know this by itself is not possible in php (to have custom functions receive other functions as arguments). I deliberately broke some code and found that there is actually a native php function call_user_fun_array beneath this (i think),
but how did they make it so that their own function can have a function as its argument?
There is a native PHP function call_user_func() Take a look on this pretty simple example.
function caller($custom_func){
return call_user_func($custom_func);
}
function make_echo(){
echo 'something';
}
caller('make_echo');
Related
I'm playing with PHP and some functional style programming.
I'm using the Functional-PHP library but question is generic to PHP (I'm using 7.2).
I try to create a callable from an imported function but what I get is
TypeError: Failed to create closure from callable: function 'pick' not found or invalid function name
Sample code:
use function Functional\pick;
class A
{
public function execute()
{
$pick1 = \Closure::fromCallable('pick');
}
}
PHP use statements define an alias for the rest of the file, but they won't affect a string referencing an imported function or class.
When you say
use function Functional\pick;
it means that in that file, you can call the Functional\pick function just using pick(...). But if you're using a string to reference it then PHP doesn't know to expand the alias.
The quickest way to resolve this is just to use the fully qualified function name when calling fromCallable:
$pick1 = \Closure::fromCallable('Functional\pick');
echo get_class($pick1);
Closure
Alternatively, if you really wanted to use the alias, you could wrap the call a level deeper with another anonymous function:
use function Functional\pick;
$pick1 = \Closure::fromCallable(function (...$args) { return pick(...$args); });
But that's a lot messier, in my opinion at least.
Edit: There's some decent discussion around this in this recent thread in php-externals
(PHP7)
Consider the following code, which tries to assign a function to a variable, and then make sure it is called only once.
class a{
static public $b;
static public function init(){
self::$b();
self::$b=function(){};
}
}
a::$b=function(){echo 'Here I do very heavy stuff, but will happen only in the first time I call init()';};
for($i=0;$i<1000;$i++){
a::init();
}
In php7 it will give an error that it expects a::$b to be a string (the function name to call).
If I use pure variables and not static members, it will work.
My question, is this suppose to work, or not, or is there a small tweak I can do for this to work without pure vars?
You can either use PHP 7 Uniform Variable Syntax:
(self::$b)();
Or a temporary variable in PHP 5+ (including 7):
$init = self::$b;
$init();
As seen on 3v4l.org.
I am a experience developer in PHP, I already know what is a function and what is a anonymous function. I also know what is the use of anonymous function and functions in PHP or in other languages. I also know the difference between function and anonymous functions.
Defination of anynonymous function is available at:
http://php.net/manual/en/functions.anonymous.php
I got the use cases of anonymous function here:
Why and how do you use anonymous functions in PHP?
But My question is how does PHP interpret/evaluate functions as arguments?
Consider below example:
<?php
function callFunction($function)
{
$function();
}
//normal function
function test()
{
echo "here";
}
//anonymous function
$function = function () {
echo 'here';
};
//call normal function test
callFunction('test');
//call anonymous function $function
callFunction($function);
In above example both function are producing same output.
But I want to know how PHP execute/interpret/evaluate both functions in callFunction method. I researched on search engins for the same but unable to found exact answer which can explain the same correctly. Please help me to understand these two cases.
Let's see the two cases separately:
<?php
function callFunction($function)
{
$function();
}
//normal function
function test()
{
echo "here";
}
//call normal function test
callFunction('test');
In this case the actual parameter for callFunction is the value "here", so a string value is passed. However, the syntax of PHP supports the concept of making it a dynamic function call: variable functions.
PHP supports the concept of variable functions. This means that if a
variable name has parentheses appended to it, PHP will look for a
function with the same name as whatever the variable evaluates to, and
will attempt to execute it. Among other things, this can be used to
implement callbacks, function tables, and so forth.
Now, onto the second case:
<?php
function callFunction($function)
{
$function();
}
//anonymous function
$function = function () {
echo 'here';
};
//call anonymous function $function
callFunction($function);
In this case $function is a Closure, as it is mentioned in the reference you linked. It is the implemented way of the function object concept in PHP. The received Closure is then executed with the parentheses operator.
You may even enforce the parameter typing in order to separate it into two different cases with type hinting:
// NOTE: string type hinting only available since PHP7
function callFunction_string(string $function)
{
$function();
}
function callFunction_closure(Closure $function)
{
$function();
}
So basically the type of the parameter received by callFunction is entirely different (string vs. Closure), however the PHP syntax is the same for both of them to execute a function call. (It's not a coincidence, it was designed like that.)
Note: similar solutions are widespread in programming languages, even in strongly typed languages like C++: just look at how function pointers, functors and lamda objects can be passed as an - templated - argument to a function, and then executed with the parentheses operator.
we are required to learn smarty right now. and i am already into creating my own functions how do i call one function inside another function?
smarty seems to call its function like
{function_name param1=val1}
i tried to put it inside the function.myfunction.php but smarty seems to parse
{ } only inside the .tpl files
is there any way i could call them like
function foo($bar){
$foo = function2(param1,param2);
return $foo + $bar;
}
That is pretty much exactly how you would do it. Your functions are written in PHP, so you use php, not smarty, notation to call your functions. You will have to make sure that the function you want to call has been included.
I want to create a function (my_function()) getting unlimited number of arguments and passing it into another function (call_another_function()).
function my_function() {
another_function($arg1, $arg2, $arg3 ... $argN);
}
So, want to call my_function(1,2,3,4,5) and get calling another_function(1,2,3,4,5)
I know that I shoud use func_get_args() to get all function arguments as array, but I don't know how to pass this arguments to another function.
Thank you.
Try call_user_func_array:
function my_function() {
$args = func_get_args();
call_user_func_array("another_function", $args);
}
In programming and computer science, this is called an apply function.
Use call_user_func_array
like
call_user_func_array('another_function', func_get_args());
It's not yet documented but you might use reflection API, especially invokeArgs.
(maybe I should have used a comment rather than a full post)
I have solved such a problem with the ...$args parameter in the function.
In my case, it was arguments forwarding to the parent construction call.
public function __construct(...$args)
{
parent::__construct(...$args);
}