PHP call_user_func vs. just calling function - php

I'm sure there's a very easy explanation for this. What is the difference between this:
function barber($type){
echo "You wanted a $type haircut, no problem\n";
}
call_user_func('barber', "mushroom");
call_user_func('barber', "shave");
... and this (and what are the benefits?):
function barber($type){
echo "You wanted a $type haircut, no problem\n";
}
barber('mushroom');
barber('shave');

Always use the actual function name when you know it.
call_user_func is for calling functions whose name you don't know ahead of time but it is much less efficient since the program has to lookup the function at runtime.

Although you can call variable function names this way:
function printIt($str) { print($str); }
$funcname = 'printIt';
$funcname('Hello world!');
there are cases where you don't know how many arguments you're passing. Consider the following:
function someFunc() {
$args = func_get_args();
// do something
}
call_user_func_array('someFunc',array('one','two','three'));
It's also handy for calling static and object methods, respectively:
call_user_func(array('someClass','someFunc'),$arg);
call_user_func(array($myObj,'someFunc'),$arg);

the call_user_func option is there so you can do things like:
$dynamicFunctionName = "barber";
call_user_func($dynamicFunctionName, 'mushroom');
where the dynamicFunctionName string could be more exciting and generated at run-time. You shouldn't use call_user_func unless you have to, because it is slower.

With PHP 7 you can use the nicer variable-function syntax everywhere. It works with static/instance functions, and it can take an array of parameters. More info at https://trowski.com/2015/06/20/php-callable-paradox
$ret = $callable(...$params);

I imagine it is useful for calling a function that you don't know the name of in advance...
Something like:
switch($value):
{
case 7:
$func = 'run';
break;
default:
$func = 'stop';
break;
}
call_user_func($func, 'stuff');

There are no benefits to call it like that, the word user mean it is for multiple user, it is useful to create modification without editing in core engine.
it used by wordpress to call user function in plugins
<?php
/* main.php */
require("core.php");
require("my_plugin.php");
the_content(); // "Hello I live in Tasikmalaya"
...
<?php
/* core.php */
$listFunc = array();
$content = "Hello I live in ###";
function add_filter($fName, $funct)
{
global $listFunc;
$listFunc[$fName] = $funct;
}
function apply_filter($funct, $content)
{
global $listFunc;
foreach ($listFunc as $key => $value)
{
if ($key == $funct and is_callable($listFunc[$key]))
{
$content = call_user_func($listFunc[$key], $content);
}
}
echo $content;
}
function the_content()
{
global $content;
$content = apply_filter('the_content', $content);
echo $content;
}
....
<?php
/* my_plugin.php */
function changeMyLocation($content){
return str_replace('###', 'Tasikmalaya', $content);
}
add_filter('the_content', 'changeMyLocation');

in your first example you're using function name which is a string. it might come from outside or be determined on the fly. that is, you don't know what function will need to be run at the moment of the code creation.

When using namespaces, call_user_func() is the only way to run a function you don't know the name of beforehand, for example:
$function = '\Utilities\SearchTools::getCurrency';
call_user_func($function,'USA');
If all your functions were in the same namespace, then it wouldn't be such an issue, as you could use something like this:
$function = 'getCurrency';
$function('USA');
Edit:
Following #Jannis saying that I'm wrong I did a little more testing, and wasn't having much luck:
<?php
namespace Foo {
class Bar {
public static function getBar() {
return 'Bar';
}
}
echo "<h1>Bar: ".\Foo\Bar::getBar()."</h1>";
// outputs 'Bar: Bar'
$function = '\Foo\Bar::getBar';
echo "<h1>Bar: ".$function()."</h1>";
// outputs 'Fatal error: Call to undefined function \Foo\Bar::getBar()'
$function = '\Foo\Bar\getBar';
echo "<h1>Bar: ".$function()."</h1>";
// outputs 'Fatal error: Call to undefined function \foo\Bar\getBar()'
}
You can see the output results here: https://3v4l.org/iBERh it seems the second method works for PHP 7 onwards, but not PHP 5.6.

Related

php class static variable inside double-quoted string [duplicate]

How can I get PHP to evaluate a static variable in double quotes?
I want to do something like this:
log("self::$CLASS $METHOD entering");
I've tried all sorts of {} combos to get the variable value of self::$CLASS, but nothing has worked. I've currently settled with string concatenation but it is a pain to type:
log(self::$CLASS . " $METHOD entering");
Sorry, you can't do that. It only works for simple expressions. See here.
Unfortunately there is no way how to do this yet. Example in one of answers here will not work, because {${self::$CLASS}} will not returns content of self::$CLASS, but will returns content of variable with name in self::$CLASS.
Here is an example, which does not returns myvar, but aaa:
$myvar = 'aaa';
self::$CLASS = 'myvar';
echo "{${self::$CLASS}}";
Use an anonymous identity function stored in a variable. This way you will have $ immediately after {:
$I = function($v) { return $v; };
$interpolated = "Doing {$I(self::FOO)} with {$I(self::BAR)}";
(I am using class constants in this example but this will work with static variables too).
I don’t know the answer to your question, but you can show the class name and method using the __METHOD__ magic constant.
<?php
class test {
public $static = 'text';
public $self = __CLASS__;
// static Method
static function author() {
return "Frank Glück";
}
// static variable
static $url = 'https://www.dozent.net';
public function dothis() {
$self = __CLASS__;
echo <<<TEST
{${!${''}=static::author()}} // works
{$self::author()} // works
{$this->self::author()} // works
${!${''}=self::author()} // works
{${$this->self}}::author()}} // don't works
${${self::author()}} // do/don't works but with notice
${#${self::author()}} // works but with # !
TEST;
}
}
$test = 'test'; // this is the trick, put the Classname into a variable
echo "{$test::author()} {$$test::$url}";
echo <<<HTML
<div>{$test::author()}</div>
<div>{$$test::$url}</div>
HTML;
$test = new test();
$test->dothis();
I know this is an old question but I find it odd that noone has suggested the [sprintf][1] function yet.
say:
<?php
class Foo {
public static $a = 'apple';
}
you would use it with:
echo sprintf( '$a value is %s', Foo::$a );
so on your example its:
log(
sprintf ( ' %s $METHOD entering', self::$CLASS )
);
//define below
function EXPR($v) { return $v; }
$E = EXPR;
//now you can use it in string
echo "hello - three is equal to $E(1+2)";
Just live with the concatenation. You'd be surprised how inefficient variable interpolation in strings can be.
And while this could fall under the umbrella of pre-optimization or micro-optimization, I just don't think you actually gain any elegance in this example.
Personally, if I'm gonna make a tiny optimization of one or the other, and my choices are "faster" and "easier to type" - I'm gonna choose "faster". Because you only type it a few times, but it's probably going to execute thousands of times.
Yes this can be done:
log("{${self::$CLASS}} $METHOD entering");

Is it possible to pass a function as another function parameter? [duplicate]

I need to pass a function as a parameter to another function and then call the passed function from within the function...This is probably easier for me to explain in code..I basically want to do something like this:
function ($functionToBeCalled)
{
call($functionToBeCalled,additional_params);
}
Is there a way to do that.. I am using PHP 4.3.9
Thanks!
I think you are looking for call_user_func.
An example from the PHP Manual:
<?php
function barber($type) {
echo "You wanted a $type haircut, no problem";
}
call_user_func('barber', "mushroom");
call_user_func('barber', "shave");
?>
function foo($function) {
$function(" World");
}
function bar($params) {
echo "Hello".$params;
}
$variable = 'bar';
foo($variable);
Additionally, you can do it this way. See variable functions.
In php this is very simple.
<?php
function here() {
print 'here';
}
function dynamo($name) {
$name();
}
//Will work
dynamo('here');
//Will fail
dynamo('not_here');
I know the original question asked about PHP 4.3, but now it's a few years later and I just wanted to advocate for my preferred way to do this in PHP 5.3 or higher.
PHP 5.3+ now includes support for anonymous functions (closures), so you can use some standard functional programming techniques, as in languages like JavaScript and Ruby (with a few caveats). Rewriting the call_user_func example above in "closure style" would look like this, which I find more elegant:
$barber = function($type) {
echo "You wanted a $type haircut, no problem\n";
};
$barber('mushroom');
$barber('shave');
Obviously, this doesn't buy you much in this example - the power and flexibility comes when you pass these anonymous functions to other functions (as in the original question). So you can do something like:
$barber_cost = function($quantity) {
return $quantity * 15;
};
$candy_shop_cost = function($quantity) {
return $quantity * 4.50; // It's Moonstruck chocolate, ok?
};
function get_cost($cost_fn, $quantity) {
return $cost_fn($quantity);
}
echo '3 haircuts cost $' . get_cost($barber_cost, 3) . "\n";
echo '6 candies cost $' . get_cost($candy_shop_cost, 6) . "\n";
This could be done with call_user_func, of course, but I find this syntax much clearer, especially once namespaces and member variables get involved.
One caveat: I'll be the first to admit I don't know exactly what's going on here, but you can't always call a closure contained in a member or static variable, and possibly in some other cases. But reassigning it to a local variable will allow it to be invoked. So, for example, this will give you an error:
$some_value = \SomeNamespace\SomeClass::$closure($arg1, $arg2);
But this simple workaround fixes the issue:
$the_closure = \SomeNamespace\SomeClass::$closure;
$some_value = $the_closure($arg1, $arg2);
You could also use call_user_func_array(). It allows you to pass an array of parameters as the second parameter so you don't have to know exactly how many variables you're passing.
If you need pass function with parameter as parameter, you can try this:
function foo ($param1){
return $param1;
}
function bar ($foo_function, $foo_param){
echo $foo_function($foo_param);
}
//call function bar
bar('foo', 'Hi there'); //this will print: 'Hi there'
phpfiddle example
Hope it'll be helpful...
If you want to do this inside a PHP Class, take a look at this code:
// Create a sample class
class Sample
{
// Our class displays 2 lists, one for images and one for paragraphs
function __construct( $args ) {
$images = $args['images'];
$items = $args['items'];
?>
<div>
<?php
// Display a list of images
$this->loop( $images, 'image' );
// notice how we pass the name of the function as a string
// Display a list of paragraphs
$this->loop( $items, 'content' );
// notice how we pass the name of the function as a string
?>
</div>
<?php
}
// Reuse the loop
function loop( $items, $type ) {
// if there are items
if ( $items ) {
// iterate through each one
foreach ( $items as $item ) {
// pass the current item to the function
$this->$type( $item );
// becomes $this->image
// becomes $this->content
}
}
}
// Display a single image
function image( $item ) {
?>
<img src="<?php echo $item['url']; ?>">
<?php
}
// Display a single paragraph
function content( $item ) {
?>
<p><?php echo $item; ?></p>
<?php
}
}
// Create 2 sample arrays
$images = array( 'image-1.jpg', 'image-2.jpg', 'image-3.jpg' );
$items = array( 'sample one', 'sample two', 'sample three' );
// Create a sample object to pass my arrays to Sample
$elements = { 'images' => $images, 'items' => $items }
// Create an Instance of Sample and pass the $elements as arguments
new Sample( $elements );

Function which produces new variable for use outside of function - PHP

How would I alter the function below to produce a new variable for use outside of the function?
PHP Function
function sizeShown ($size)
{
// *** Continental Adult Sizes ***
if (strpos($size, 'continental-')!== false)
{
$size = preg_replace("/\D+/", '', $size);
$searchsize = 'quantity_c_size_' . $size;
}
return $searchsize;
Example
<?php
sizeShown($size);
$searchsize;
?>
This currently produces a null value and Notice: undefined variable.
So the function takes one argument, a variable containing a string relating to size. It checks the variable for the string 'continental-', if found it trims the string of everything except the numbers. A new variable $searchsize is created which appends 'quantity_c_size_' to the value stored in $size.
So the result would be like so ... quantity_c_size_45
I want to be able to call $searchsize outside of the function within the same script.
Can anybody provide a solution?
Thanks.
Try using the global keyword, like so:
function test () {
global $test_var;
$test_var = 'Hello World!';
}
test();
echo $test_var;
However, this is usually not a good coding practice. So I would suggest the following:
function test () {
return 'Hello World!';
}
$test_var = test();
echo $test_var;
In the function 'sizeShown' you are just returning the function. You forgot to echo the function when you call your function.
echo sizeShown($size);
echo $searchsize;
?>
But the way you call $searchsize is not possible.
This is an old question, and I might not be understanding the OP's question properly, but why couldn't you just do this:
<?php
$searchsize = sizeShown($size);
?>
You're already returning $searchsize from the sizeShown method. So if you simply assign the result of the function to the $sizeShown variable, you should have what you want.

Trying to create a function with a variable PHP

I am trying to do something like this:
//function name
$str = 'bla()';
//make function with string as name
function $str{
echo 'yey';
}
//Call the function by string name
bla();
You could use eval() to attempt this task. But I really do NOT suggest it:
// name of the function
$str = 'bla';
// php code you want to execute inside
$inside = '';
eval("
function $str() { $inside }
");
Or you could also use an anonymous function:
$name = function() {
// code
};
// execution
$name();
Als if you are just trying to call a dynamic function just use call_user_func() like this:
// name of the function
$str = 'bla';
// paramters to the function
$param = array();
call_user_func($str, $param);
But I think you are doing something wrong. This kind of "hacks" are sign of bad application architecture.
References
eval()
call_user_func()
Anonymous functions
I'll suggest you, not to use like this. But if still you want to do this,
<?php
$greet = function($name)
{
printf("Hello %s\r\n", $name);
};
$greet('World');
$greet('PHP');
?>
Check here
And you are required to use PHP 5.3
Whenever a function completes, it RETURNS a value. If no value is set to be returned, 0 is returned.
If you would like to be able to do as you have asked, you could do the following:
function blah($string="Blah"){
return($string);
}
echo blah("Banana"); //echo's Banana
echo blah(); //echo's Blah
$str = blah("Apple"); //Sets $str to Apple

php create function from string value

I just simply want to create a function name with a string value.
Something like this:
$ns = 'test';
function $ns.'_this'(){}
test_this();
It of course throws an error.
I've tried with:
function {$ns}.'_this'
function {$ns.'_this'}
but no luck.
Any thoughts?
You can use create_function to create a function from provided string.
Example (php.net)
<?php
$newfunc = create_function('$a,$b', 'return "ln($a) + ln($b) = " . log($a * $b);');
echo "New anonymous function: $newfunc\n";
echo $newfunc(2, M_E) . "\n";
// outputs
// New anonymous function: lambda_1
// ln(2) + ln(2.718281828459) = 1.6931471805599
?>
This is not possible. If all you want to do is, to prefix all functions with some common string, maybe you want to use namespaces?
namespace foo {
function bar() {}
function rab() {}
function abr() {}
}
// access from global namespace is as follows:
namespace {
foo\bar(); foo\rab(); foo\abr();
}
file with function (somefile.php)
function outputFunctionCode($function_name)
{?>
function <?php echo $function_name ?>()
{
//your code
}
<?php }
file with code which "declares" the function:
ob_start();
include("somefile.php");
outputFunctionCode("myDynamicFunction");
$contents = ob_get_contents();
ob_end_clean();
$file = fopen("somefile2.php", "w");
fwrite($file,$contents);
fclose($file);
include("somefile2.php");
It is ugly, but then again, it is an extremely bad idea to declare functions with dynamic names.
using "eval" is not a good practice, but that may serve the purpose similar to your requirements sometimes.
<?php
$ns = 'test';
$funcName = $ns.'_this';
eval("function $funcName(){ echo 1;}");
test_this();
?>
Is this what you are looking for?
<?php
function foo($a) { print 'foo called'.$a; }
$myfunctionNameStr = 'foo';
$myfunctionNameStr(2);
?>
Cause i don't think that you can dynamically construct a function declaration. You can decide at 'runtime' the value of the $myfunctionNameStr though.

Categories