In PHP, How to call function in string?

Go To StackoverFlow.com

7

say,string is:

$str="abcdefg foo() hijklmopqrst";

How to let php call foo() and insert the return string to this string?

2012-04-03 22:58
by lovespring
Very unpleasantly. Do you have a list of functions that you want to allow this for, or any function in general? (Also, you have considered the security and performance implications of this, yes? - Corbin 2012-04-03 22:59
You can use eval() but it's not widely recommended - Panagiotis 2012-04-03 23:00
Please give us more information about your code. Where is this string coming from? You mentioned an API - savinger 2012-04-03 23:03
This: http://stackoverflow.com/questions/1005857/how-to-call-php-function-from-string-stored-in-a-variabl - FrogInABox 2012-04-03 23:12
Please don't change already answered question into another question. Open a new question instead - Basti 2012-04-04 00:19
Duplicate of http://stackoverflow.com/q/3822839/106623 - Kai Noack 2016-08-09 12:42


7

$str="abcdefg foo() hijklmopqrst";
function foo() {return "bar";}

$replaced = preg_replace_callback("~([a-z]+)\(\)~", 
     function ($m){
          return $m[1]();
     }, $str);

output:

$replaced == 'abcdefg bar hijklmopqrst';

This will allow any lower-case letters as function name. If you need any other symbols, add them to the pattern, i.e. [a-zA-Z_].

Be VERY careful which functions you allow to be called. You should at least check if $m[1] contains a whitelisted function to not allow remote code injection attacks.

$allowedFunctions = array("foo", "bar" /*, ...*/);

$replaced = preg_replace_callback("~([a-z]+)\(\)~", 
     function ($m) use ($allowedFunctions) {
          if (!in_array($m[1], $allowedFunctions))
              return $m[0]; // Don't replace and maybe add some errors.

          return $m[1]();
     }, $str);

Testrun on "abcdefg foo() bat() hijklmopqrst" outputs "abcdefg bar bat() hijklmopqrst".

Optimisation for whitelisting approach (building pattern dynamically from allowed function names, i.e. (foo|bar).

$allowedFunctions = array("foo", "bar");

$replaced = preg_replace_callback("~(".implode("|",$allowedFunctions).")\(\)~", 
     function ($m) {
          return $m[1]();
     }, $str);
2012-04-03 23:08
by Basti
you are a good programmer - lovespring 2012-04-03 23:25
What if the function has parameters - Munna Khan 2018-03-02 16:41


23

If you're calling a method of some class, you can use normal variable expansion. For example:

<?php
class thingie {

  public function sayHello() {
    return "hello";
  }

}

$t = new thingie();
echo "thingie says: {$t->sayHello()}";

This will output:

thingie says: hello

Note that the braces around the call are required.

2013-11-25 20:27
by HonoredMule
But it seems calling a global function this way, won't wor - Opux 2016-10-31 16:57
By wrapping the global functions you want to support in an object of methods, you can control the footprint of exposure to bugs and security leaks. I think you'd be hard-pressed to find an easier way to /safely/ offer such power. Your wrapper methods can even perform additional validation/restriction if needed - HonoredMule 2018-06-27 13:57


15

Just use this:

$str = "abcdefg".foo()."hijklmnopqrstuvwxyz";

It will call function during string creation.

2012-04-03 22:59
by Frederick Marcoux
the API just give me a string, So, cannot make this format - lovespring 2012-04-03 23:02
What is the function you want to use - Frederick Marcoux 2012-04-03 23:03
@lovespring This is a horrible set up. What API are you using that would do this - Nilpo 2012-04-03 23:05
I can call but cannot modify a code from another person, he didn't give me a API, I have to hook the $str to inject my code - lovespring 2012-04-03 23:06
@lovespring In clear? - Frederick Marcoux 2012-04-03 23:09


5

$foo = foo();
$str = "abcdefg {$foo} hijklmopqrst";
2012-04-03 22:59
by savinger
I have to call the foo() in the $str time - lovespring 2012-04-03 23:00
@lovespring you mean at some later point? Perhaps you are looking for eval($str)savinger 2012-04-03 23:01


5

function foo()
{
    return 'Hi';
}
$my_foo = 'foo';
echo "{$my_foo()}";
2017-05-03 12:08
by v.babak
This is a great "trick." You can even pass parameters or other variables to it, ie. echo "{$my_foo('bar')}" or echo "{$my_foo($bar)}" - especially useful when building SQL queries with many escaped values - Nick D 2017-05-24 21:17
Wow, great trick - pineappleman 2017-07-20 11:59


3

To get arbitrary expressions being evaluated from a double-quoted string you can speculate on variable-functions:

<?php
// A user function
function foo() {
    return 'bar';
}

/**
 * The hack
 *
 * @param $v mixed Value
 * return mixed Value (untouched)
 */
$_ = function ( $v ) {
    return $v;
};

// Happy hacking
echo "Foo is {$_( foo() )} and the sum is {$_( 41 + 1 )}...{$_( str_repeat( ' arrh', 3 ) )}!";

Result:

Foo is bar and the sum is 42... arrrh arrrh arrrh!

References:

2018-02-07 14:03
by Valerio Bozz


2

Its still not possible, There are hacks available but not what I would recommend rather suggest to stick with old school dot operator i.e. $str="abcdefg ". foo() ." hijklmopqrst";

As per the Complex (curly) syntax documentation

Note:
Functions, method calls, static class variables, and class constants inside {$} work since PHP 5. However, the value accessed will be interpreted as the name of a variable in the scope in which the string is defined. Using single curly braces ({}) will not work for accessing the return values of functions or methods or the values of class constants or static class variables.

2018-10-18 06:30
by Mubashar Ahmad