在HEREDOCstring中调用PHP函数

在PHP中,HEREDOCstring声明对于输出html块是非常有用的。 你可以通过在$前加上variables来parsingvariables,但是对于更复杂的语法(比如$ var [2] [3]),你必须把你的expression式放在{}括号中。

在PHP 5中,实际上可以在HEREDOCstring中的{}大括号内进行函数调用,但是必须经过一些工作。 函数名称本身必须存储在一个variables中,您必须像调用一个dynamic命名的函数那样调用它。 例如:

$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(); ?> 

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

所以,我的问题的本质是:有没有更好的方法来处理这个问题?

基于响应编辑:它确实看起来像某种模板引擎会让我的生活更容易,但这将需要我基本上颠倒我平时的PHP风格。 这不是一件坏事,但它解释了我的惰性。我想找出让生活更轻松的方法,所以我现在正在研究模板。

个人而言,我完全不会使用HEREDOC。 它只是没有build立一个良好的“模板build设”系统。 所有的HTML都被locking在一个有几个缺点的string中

  • 所见即所得没有select
  • 没有代码完成从IDE的HTML
  • 输出(HTML)locking到逻辑文件
  • 你最终不得不像现在要做的那样使用黑客来实现更复杂的模板,比如循环

获得一个基本的模板引擎,或者只是使用PHP与包​​含 – 这就是为什么语言有<?php?>分隔符。

template_file.php

 <html> <head> <title><?php echo $page_title; ?></title> </head> <body> <?php echo getPageContent(); ?> </body> 

的index.php

 <?php $page_title = "This is a simple demo"; function getPageContent() { return '<p>Hello World!</p>'; } include('template_file.php'); 

如果你真的想这样做,但比使用一个类更简单,你可以使用:

 function fn($data) { return $data; } $fn = 'fn'; $my_string = <<<EOT Number of seconds since the Unix Epoch: {$fn(time())} EOT; 

我会做以下几点:

 $string = <<< heredoc plain text and now a function: %s heredoc; $string = sprintf($string, testfunction()); 

不知道如果你认为这是更优雅…

试试这个(作为一个全局variables,或者当你需要的时候实例化):

 <?php class Fn { public function __call($name, $args) { if (function_exists($name)) { return call_user_func_array($name, $args); } } } $fn = new Fn(); ?> 

现在任何函数调用都要经过$fn实例。 所以现有的函数testfunction()可以在heredoc中调用{$fn->testfunction()}

基本上我们把所有的函数都包装到类实例中,并且使用PHP的__call magic方法将类方法映射到需要调用的实际函数。

我有点晚了,但我随机碰到它。 对于任何未来的读者,我可能会这样做:

我只会使用输出缓冲区。 所以基本上,你使用ob_start()开始缓冲,然后在其中包含你的“模板文件”和任何函数,variables等,获取缓冲区的内容并将它们写入一个string,然后closures缓冲区。 然后,您已经使用了所需的任何variables,您可以运行任何函数,并且仍然可以在IDE中使用HTML语法高亮显示。

这是我的意思:

模板文件:

 <?php echo "plain text and now a function: " . testfunction(); ?> 

脚本:

 <?php ob_start(); include "template_file.php"; $output_string = ob_get_contents(); ob_end_clean(); echo $output_string; ?> 

所以脚本在其缓冲区中包含了template_file.php,运行了任何函数/方法,并沿途分配了任何variables。 然后,只需将缓冲区的内容logging到一个variables中,然后根据需要执行操作。

那样的话,如果你不想在第二时间将它回显到页面上,那么你就不必这样做。 输出之前,您可以循环并继续添加到string。

如果你不想使用模板引擎,我认为这是最好的方法。

这段代码将在userscope中定义具有您定义函数名称的variables,并将它们绑定到包含相同名称的string。 让我来certificate一下。

 function add ($int) { return $int + 1; } $f=get_defined_functions();foreach($f[user]as$v){$$v=$v;} $string = <<< heredoc plain text and now a function: {$add(1)} heredoc; 

现在将工作。

我认为使用heredoc非常适合生成HTML代码。 例如,我发现以下几乎完全不可读。

 <html> <head> <title><?php echo $page_title; ?></title> </head> <body> <?php echo getPageContent(); ?> </body> 

但是,为了实现简单性,您必须在开始之前评估function。 我不相信这是一个可怕的约束,因为这样做,你最终将计算与显示分开,这通常是一个好主意。

我认为以下是非常可读的:

 $page_content = getPageContent(); print <<<END <html> <head> <title>$page_title</title> </head> <body> $page_content </body> END; 

不幸的是,尽pipe在你的问题中提出了一个很好的build议,把函数绑定到一个variables上,但是最后它增加了一层代码的复杂性,这是不值得的,并且使得代码更不可读, heredoc的主要优点。

我想看看Smarty作为一个模板引擎 – 我自己也没有尝试过任何其他的模板引擎,但是它对我很好。

如果你想坚持你当前的方法sans模板,输出缓冲有什么不好的地方? 它会给你更多的灵活性,而不必声明variables,这些variables是你想要调用的函数的名字。

发现包装function在这里很好的解决scheme: http : //blog.nazdrave.net/?p=626

 function heredoc($param) { // just return whatever has been passed to us return $param; } $heredoc = 'heredoc'; $string = <<<HEREDOC \$heredoc is now a generic function that can be used in all sorts of ways: Output the result of a function: {$heredoc(date('r'))} Output the value of a constant: {$heredoc(__FILE__)} Static methods work just as well: {$heredoc(MyClass::getSomething())} 2 + 2 equals {$heredoc(2+2)} HEREDOC; // The same works not only with HEREDOC strings, // but with double-quoted strings as well: $string = "{$heredoc(2+2)}"; 

为了完整性,你也可以使用!${''}黑魔法:

 echo <<<EOT One month ago was ${!${''} = date('Ymd H:i:s', strtotime('-1 month'))}. EOT; 

您几乎可以描述在模板引擎中发生的事情。 你显然知道php很好。 你有没有考虑过看一个实际的模板引擎?

有点晚了,但仍然。 这在heredoc中是可能的!

看看在PHP手册中,“复杂(curl)语法”

这里使用@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语法的一个很好的用法是在数据库中生成具有主从关系的巨大forms。 可以使用FOR控件中的HEREDOCfunction,在每个字段名称后添加后缀。 这是一个典型的服务器端任务。

人们应该注意,它也适用于双引号string。

http://www.php.net/manual/en/language.types.string.php

无论如何,有趣的提示。

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

你忘记了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

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

你应该试试 。 ETO结束后; 命令你应该给一个回车。