How do I immediately execute an anonymous function in PHP? - php

In JavaScript, you can define anonymous functions that are executed immediately:
(function () { /* do something */ })()
Can you do something like that in PHP?

For versions prior to PHP 7, the only way to execute them immediately I can think of is
call_user_func(function() { echo 'executed'; });
With current versions of PHP, you can just do
(function() { echo 'executed'; })();

In PHP 7 is to do the same in javascript
$gen = (function() {
yield 1;
yield 2;
return 3;
})();
foreach ($gen as $val) {
echo $val, PHP_EOL;
}
echo $gen->getReturn(), PHP_EOL;
The output is:
1
2
3

This is the simplest for PHP 7.0 or later.
(function() {echo 'Hi';})();
It means create closure, then call it as function by following "()". Works just like JS thanks to uniform variable evaluation order.
https://3v4l.org/06EL3

Well of course you can use call_user_func, but there's still another pretty simple alternative:
<?php
// we simply need to write a simple function called run:
function run($f){
$f();
}
// and then we can use it like this:
run(function(){
echo "do something";
});
?>

(new ReflectionFunction(function() {
// body function
}))->invoke();

Note, accepted answer is fine but it takes 1.41x as long (41% slower) than declaring a function and calling it in two lines.
[I know it's not really a new answer but I felt it was valuable to add this somewhere for visitors.]
Details:
<?php
# Tags: benchmark, call_user_func, anonymous function
require_once("Benchmark.php");
bench(array(
'test1_anonfunc_call' => function(){
$f = function(){
$x = 123;
};
$f();
},
'test2_anonfunc_call_user_func' => function(){
call_user_func(
function(){
$x = 123;
}
);
}
), 10000);
?>
Results:
$ php test8.php
test1_anonfunc_call took 0.0081379413604736s (1228812.0001172/s)
test2_anonfunc_call_user_func took 0.011472940444946s (871616.13432805/s)

This isn't a direct answer, but a workaround. Using PHP >= 7. Defining an anonymous class with a named method and constructing the class and calling the method right away.
$var = (new class() { // Anonymous class
function cool() { // Named method
return 'neato';
}
})->cool(); // Instantiate the anonymous class and call the named method
echo $var; // Echos neato to console.

I tried it out this way, but it's more verbose than the top answer by using any operator (or function) that allows you to define the function first:
$value = $hack == ($hack = function(){
// just a hack way of executing an anonymous function
return array(0, 1, 2, 3);
}) ? $hack() : $hack();

Not executed inmediately, but close to ;)
<?php
$var = (function(){ echo 'do something'; });
$var();
?>

Related

How to define function name using variable?

how to define function name (in PHP) using variable, like this?
$a='myFuncion';
function $a() {.......}
or like that?
The only way I know to give a fixed name to a function is to use eval, which I would not suggest.
More likely, what you want is to stuff a function IN a variable, and then just call that.
Try this:
$a = function() {
echo 'This is called an anonymous function.';
}
$a();
EDIT:
If you want to be accessible from other files, then use GLOBAL variable:
$GLOBALS['variable_name'] = 'my_func_123';
${$GLOBALS['variable_name']} = function() {
echo 'This is called an anonymous function.';
};
// Executing my_func_123()
${$GLOBALS['variable_name']}();
See also: http://php.net/manual/en/functions.anonymous.php

Can non-anonymous functions in PHP using 'use' keyword?

Can non-anonymous functions in PHP using 'use' keyword? Or it is available for anonymous functions only.
Can I write a php file like this
// L.php
// assume $_texts is in this context..
$_language = null;
function L_init($language) use (&$_language)
{
$_language = $language;
}
function L($key) use ($_texts, $_language)
{
$_texts[$_language][$key];
}
So, another file can use it like this
// client.php
require_once 'L.php';
L_init('en');
echo L('GREETING'); // Will output localize string of key 'GREETING'
It is available for anonymous functions, but you can assign it to a variable:
$some_external_var = "World!";
$function = function() use($some_external_var){
echo "Hello ".$some_external_var;
};
Finally you can invoke it with:
call_user_func($function);
or just:
$function();
No you can't.
The code generate syntax errors.

Using closures in an array

I have a code similar to this:
$name = '_DBR'; // This comes from a function call
$this->_Inits['_DBR'] = function () { return get_library('Database')->getConnection('users', 'read'); };
$inits = $this->_Inits[$name];
$result = $inits(); // ERROR: Function name must be a string
return $result;
The error I get is:
Function name must be a string in xxxx
Is there any ways I could use an array to store multiple closures and is there a working way to access them?
I use PHP 5.4.3
This works fine for me in php 5.3.10.
$m = array();
$m['fish'] = function() { print "Hello\n"; };
$f = $m['fish'];
$f();
Yeah, use call_user_func instead.

JavaScript Pass Variables Through Reference

Is there an equivalent in JavaScript for PHP's reference passing of variables?
[PHP]:
function addToEnd(&$theRefVar,$str)
{
$theRefVar.=$str;
}
$myVar="Hello";
addToEnd($myVar," World!");
print $myVar;//Outputs: Hello World!
How would the same code look in JavaScript if possible?
Thank you!
Objects are passed as references.
function addToEnd(obj,$str)
{
obj.setting += $str;
}
var foo = {setting:"Hello"};
addToEnd(foo , " World!");
console.log(foo.setting); // Outputs: Hello World!
Edit:
As posted in comments below, CMS made mention of a great article.
It should be mentioned that there is no true way to pass anything by reference in JavaScript. The first line has been changed from "by reference" to "as reference". This workaround is merely as close as you're going to get (even globals act funny sometimes).
As CMS, HoLyVieR, and Matthew point out, the distinction should be made that foo is a reference to an object and that reference is passed by value to the function.
The following is included as another way to work on the object's property, to make your function definition more robust.
function addToEnd(obj,prop,$str)
{
obj[prop] += $str;
}
var foo = {setting:"Hello"};
addToEnd(foo , 'setting' , " World!");
console.log(foo.setting); // Outputs: Hello World!
In Javascript there is no passing variable by reference like in PHP. There is a possible workaround to do something similar.
function addToEnd(obj, str)
{
obj.value += str;
}
myVar={value:"Hello"};
addToEnd(myVar, " World");
alert(myVar.value); //Outputs: Hello World!
In this example, what happens is that you pass an object to the function and inside of it, you are modifying the object (not the variable, the variable is still pointing to the same object). This is why this is not passing variable by reference has vol7ron incorrectly stated.
The other answers/comments describe the situation well enough, but I thought I'd offer and alternative if you need that style of functionality, by using a callback.
var someText = "asd";
addToEnd(someText, "fgh", function(val) { someText = val; });
and
function addToEnd(original, str, setValue)
{
setValue(original += str);
}
but a better solution would be
var someText = "asd";
someText = addToEnd(someText, "fgh");
and
function addToEnd(original, str)
{
return original += str;
}
try this:
// function
function func(param,callback){
if(param){
if(typeof callback=='function') {
callback.call(this,param);
}
return true;
}
return false;
}
// calling function
var variable=0;
returnValue=func(10,function(reference){variable=reference});
alert(returnValue+'/'+variable);

How do I implement a callback in PHP?

How are callbacks written in PHP?
The manual uses the terms "callback" and "callable" interchangeably, however, "callback" traditionally refers to a string or array value that acts like a function pointer, referencing a function or class method for future invocation. This has allowed some elements of functional programming since PHP 4. The flavors are:
$cb1 = 'someGlobalFunction';
$cb2 = ['ClassName', 'someStaticMethod'];
$cb3 = [$object, 'somePublicMethod'];
// this syntax is callable since PHP 5.2.3 but a string containing it
// cannot be called directly
$cb2 = 'ClassName::someStaticMethod';
$cb2(); // fatal error
// legacy syntax for PHP 4
$cb3 = array(&$object, 'somePublicMethod');
This is a safe way to use callable values in general:
if (is_callable($cb2)) {
// Autoloading will be invoked to load the class "ClassName" if it's not
// yet defined, and PHP will check that the class has a method
// "someStaticMethod". Note that is_callable() will NOT verify that the
// method can safely be executed in static context.
$returnValue = call_user_func($cb2, $arg1, $arg2);
}
Modern PHP versions allow the first three formats above to be invoked directly as $cb(). call_user_func and call_user_func_array support all the above.
See: http://php.net/manual/en/language.types.callable.php
Notes/Caveats:
If the function/class is namespaced, the string must contain the fully-qualified name. E.g. ['Vendor\Package\Foo', 'method']
call_user_func does not support passing non-objects by reference, so you can either use call_user_func_array or, in later PHP versions, save the callback to a var and use the direct syntax: $cb();
Objects with an __invoke() method (including anonymous functions) fall under the category "callable" and can be used the same way, but I personally don't associate these with the legacy "callback" term.
The legacy create_function() creates a global function and returns its name. It's a wrapper for eval() and anonymous functions should be used instead.
With PHP 5.3, you can now do this:
function doIt($callback) { $callback(); }
doIt(function() {
// this will be done
});
Finally a nice way to do it. A great addition to PHP, because callbacks are awesome.
Implementation of a callback is done like so
// This function uses a callback function.
function doIt($callback)
{
$data = "this is my data";
$callback($data);
}
// This is a sample callback function for doIt().
function myCallback($data)
{
print 'Data is: ' . $data . "\n";
}
// Call doIt() and pass our sample callback function's name.
doIt('myCallback');
Displays: Data is: this is my data
One nifty trick that I've recently found is to use PHP's create_function() to create an anonymous/lambda function for one-shot use. It's useful for PHP functions like array_map(), preg_replace_callback(), or usort() that use callbacks for custom processing. It looks pretty much like it does an eval() under the covers, but it's still a nice functional-style way to use PHP.
well... with 5.3 on the horizon, all will be better, because with 5.3, we'll get closures and with them anonymous functions
http://wiki.php.net/rfc/closures
You will want to verify whatever your calling is valid. For example, in the case of a specific function, you will want to check and see if the function exists:
function doIt($callback) {
if(function_exists($callback)) {
$callback();
} else {
// some error handling
}
}
create_function did not work for me inside a class. I had to use call_user_func.
<?php
class Dispatcher {
//Added explicit callback declaration.
var $callback;
public function Dispatcher( $callback ){
$this->callback = $callback;
}
public function asynchronous_method(){
//do asynch stuff, like fwrite...then, fire callback.
if ( isset( $this->callback ) ) {
if (function_exists( $this->callback )) call_user_func( $this->callback, "File done!" );
}
}
}
Then, to use:
<?php
include_once('Dispatcher.php');
$d = new Dispatcher( 'do_callback' );
$d->asynchronous_method();
function do_callback( $data ){
print 'Data is: ' . $data . "\n";
}
?>
[Edit]
Added a missing parenthesis.
Also, added the callback declaration, I prefer it that way.
For those who don't care about breaking compatibility with PHP < 5.4, I'd suggest using type hinting to make a cleaner implementation.
function call_with_hello_and_append_world( callable $callback )
{
// No need to check $closure because of the type hint
return $callback( "hello" )."world";
}
function append_space( $string )
{
return $string." ";
}
$output1 = call_with_hello_and_append_world( function( $string ) { return $string." "; } );
var_dump( $output1 ); // string(11) "hello world"
$output2 = call_with_hello_and_append_world( "append_space" );
var_dump( $output2 ); // string(11) "hello world"
$old_lambda = create_function( '$string', 'return $string." ";' );
$output3 = call_with_hello_and_append_world( $old_lambda );
var_dump( $output3 ); // string(11) "hello world"
I cringe every time I use create_function() in php.
Parameters are a coma separated string, the whole function body in a string... Argh... I think they could not have made it uglier even if they tried.
Unfortunately, it is the only choice when creating a named function is not worth the trouble.

Categories