在HEREDOC字符串中调用PHP函数

105
在PHP中,HEREDOC字符串声明非常有用,可以用于输出一块HTML。只需在变量前加上$,就可以解析变量。但对于更复杂的语法(例如$var [2] [3]),您必须将表达式放在{}括号中。
在PHP 5中,实际上可以在HEREDOC字符串内的{}括号中调用函数,但您需要进行一些工作。函数名称本身必须存储在变量中,并且必须像动态命名函数一样调用它。例如:
$fn = 'testfunction';
function testfunction() { return 'ok'; }
$string = <<< heredoc
plain text and now a function: {$fn()}
heredoc;

你可以看到,这比仅仅是:

稍微有些混乱。
$string = <<< heredoc
plain text and now a function: {testfunction()}
heredoc;

除了第一个代码示例之外,还有其他的方法,比如打破HEREDOC来调用函数,或者反转问题并执行类似以下的操作:

?>
<!-- directly output html and only breaking into php for the function -->
plain text and now a function: <?PHP print testfunction(); ?>

后者的缺点在于输出被直接放入输出流中(除非我使用输出缓冲),这可能不是我想要的。

因此,我的问题的实质是:有没有更优雅的方法来解决这个问题?

根据回复进行编辑:看起来某种模板引擎会让我的生活更加轻松,但这需要我基本上颠倒我的常规PHP风格。这并不是什么坏事,但它解释了我的惯性... 我愿意想办法让生活更容易,所以我现在正在研究模板。


3
这并不是对你问题的直接回答,但鉴于heredoc语句中函数调用支持较差,我通常会在打印heredoc之前生成需要的字符串。然后,在heredoc中,我可以简单地使用Text {$string1} Text {$string2} Text这样的表达式。 - rinogo
17个回答

4

你忘记了lambda函数:

$or=function($c,$t,$f){return$c?$t:$f;};
echo <<<TRUEFALSE
    The best color ever is {$or(rand(0,1),'green','black')}
TRUEFALSE;

您也可以使用create_function函数。

3

我已经在第一个示例中使用了该语法;它的缺点是必须先将函数名放入变量中,然后才能在heredoc部分的花括号内调用它,这正是我试图避免的。 - Doug Kavendek

3
我建议你作为模板引擎尝试一下Smarty - 我个人没有尝试过其他的模板引擎,但是这个对我来说做得很好。
如果你想继续使用当前方法而不使用模板,则输出缓冲有什么坏处呢?它会比声明变量更加灵活,这些变量是你想要调用的函数的字符串名称。

请在您的答案中添加一些解释,以便其他人可以从中学习。查看Smarty如何解决最初的问题? - Nico Haase

2

这里有一个很好的使用@CJDennis提议的例子:

function double($i)
{ return $i*2; }

function triple($i)
{ return $i*3;}

$tab = 'double';
echo "{$tab(5)} is $tab 5<br>";

$tab = 'triple';
echo "{$tab(5)} is $tab 5<br>";

例如,HEREDOC语法的一个好用途是在数据库中生成具有主从关系的大型表单。可以在FOR控件内使用HEREDOC功能,在每个字段名后添加后缀。这是一个典型的服务器端任务。

1
<div><?=<<<heredoc
Use heredoc and functions in ONE statement.
Show lower case ABC="
heredoc
. strtolower('ABC') . <<<heredoc
".  And that is it!
heredoc
?></div>

1

-1
<?php
echo <<<ETO
<h1>Hellow ETO</h1>
ETO;

你应该试一下。在结束 ETO; 命令后,你应该按回车键。


请在你的回答中添加一些解释,以便其他人可以从中学习。您分享的代码未在heredoc中调用任何函数。 - Nico Haase

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接