Let's say my string is:
$str = "abcdefg foo() hijklmopqrst";
How do I let PHP call the function foo() and insert the returning string to the rest of that string?
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.
function foo()
{
return 'Hi';
}
$my_foo = 'foo';
echo "{$my_foo()}";
echo "{$my_foo('bar')}" or echo "{$my_foo($bar)}" - especially useful when building SQL queries with many escaped values.Just use this:
$str = "abcdefg".foo()."hijklmnopqrstuvwxyz";
It will call function during string creation.
$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);
No. There is no such native construct to call functions like "Date is: date() yeah yeah" and processing such string sounds like a performance nightmare, and a security nightmare.
Good news: you may really just use printf() or sprintf():
<?php
printf(
'Year is: %s, and month is: %s',
date('Y'),
date('m')
);
Output:
Year is: 2025, and month is: 09
Documentation about printf:
Well. Yes. If you really need to get arbitrary expressions being evaluated from a double-quoted string, you can implement a workaround, speculating on a feature called variable-functions:
<?php
/**
* Hack to dynamically process things inside strings.
*
* @param mixed $v Value
* return mixed Same value
*/
$GLOBALS['_'] = function ($v) {
return $v;
};
// Happy hacking in global context
echo "Year is: {$_(date('Y'))} and the max function returns {$_(max( 1, 2, 3 ))}...{$_(str_repeat(' arrh', 3))}! ";
// Happy hacking inside functions
function test() {
global $_;
echo "Also works in functions! Here random: {$_(random_int(0, 10))}. Yeah!";
}
test();
Result:
Year is 2025 and the max function returns 3... arrh arrh arrh!
Also works in functions! Here random: 8. Yeah!
The example is not limited to date(), max() and str_repeat(): you can surely define your own functions like foo() and just call them, as long as they return a valid string.
This example creates a simple global variable called just $_ and this name is adopted just to be very very short, so you type less. This variable contains a simple function which just returns the first argument. This is syntax sugar for you, since functions are not easily expanded as-is inside a string. Instead, variables are expanded easily. That's it.
I wonder if PHP will ever introduce a native feature to do that (note: I've written this note in 2018). In the meanwhile, this is the only workaround.
References:
Note that, with this hack, the functions are immediately expanded when you define the string. So, do not expect to store the string in a variable and see the result changed every time you print it.
Another reason why you should not use this hack, is that it's not compatible with many internationalization workflows. For example it's not compatible with GNU Gettext.
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.
<?
function foo($b)
{
return "Hi $b";
}
$bar = 'bario';
$my_foo = 'foo';
echo "<br>1 {$my_foo($bar)}";
$myfoo = foo; // my 'version'
echo "<br>2 {$myfoo($bar)}";
// the following is nogo; php error! $myfoo can not be called as function because it got the return value if foo() which is a string.
// means https://stackoverflow.com/users/517676/savinger answer above is wrong; this program doesn't print "<br>end":
$myfoo = foo();
echo "<br>3 {$myfoo($bar)}";
echo "<br>end";
?>
The output is:
1 Hi bario
2 Hi bario
$myfoo = foo; is not "your" version but a PHP error. The only working solution is the first one and it's already provided. This answer has zero value.
sprintf()?sprintf("abcdefg %s hijklmopqrst", foo())is really maybe something that may cover your original use-case (?) but it's not really what is asked here. Thanks for this small late clarification