在herdoc字符串中调用PHP函数

在herdoc字符串中调用PHP函数,php,string,heredoc,Php,String,Heredoc,在PHP中,herdoc字符串声明对于输出html块非常有用。只需在变量前加$就可以让它解析变量,但对于更复杂的语法(如$var[2][3]),必须将表达式放在{}大括号内 在PHP5中,实际上可以在herdoc字符串中的{}大括号内进行函数调用,但您必须完成一些工作。函数名本身必须存储在变量中,您必须像调用动态命名函数一样调用它。例如: $fn = 'testfunction'; function testfunction() { return 'ok'; } $string = <&l

在PHP中,herdoc字符串声明对于输出html块非常有用。只需在变量前加$就可以让它解析变量,但对于更复杂的语法(如$var[2][3]),必须将表达式放在{}大括号内

在PHP5中,实际上可以在herdoc字符串中的{}大括号内进行函数调用,但您必须完成一些工作。函数名本身必须存储在变量中,您必须像调用动态命名函数一样调用它。例如:

$fn = 'testfunction';
function testfunction() { return 'ok'; }
$string = <<< heredoc
plain text and now a function: {$fn()}
heredoc;
$fn='testfunction';
函数testfunction(){返回'ok';}

$string=我将执行以下操作:

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

$string=就我个人而言,我根本不会使用herdeoc。它只是不适合一个好的“模板构建”系统。所有HTML都被锁定在一个字符串中,这有几个缺点

  • 无所见即所得选项
  • IDE中的HTML没有代码完成
  • 输出(HTML)锁定到逻辑文件
  • 你最终不得不使用像你现在尝试做的那样的黑客来实现更复杂的模板,比如循环
获取一个基本的模板引擎,或者只使用PHP和includes——这就是为什么该语言有
分隔符

模板文件.php

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

$page_title = "This is a simple demo";

function getPageContent() {
    return '<p>Hello World!</p>';
}

include('template_file.php');

index.php

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

$page_title = "This is a simple demo";

function getPageContent() {
    return '<p>Hello World!</p>';
}

include('template_file.php');
我想看看作为一个模板引擎,我自己还没有尝试过任何其他的,但它做得很好


如果您想坚持使用当前的方法SAN模板,那么输出缓冲有什么不好?它比必须声明变量(您要调用的函数的字符串名)更灵活。

我有点晚了,但我偶然发现了它。对于未来的读者,我可能会这样做:

我只需要使用一个输出缓冲区。因此,基本上,您可以使用ob_start()启动缓冲区,然后将包含函数、变量等的“模板文件”包含在其中,获取缓冲区的内容并将其写入字符串,然后关闭缓冲区。然后,您已经使用了所需的任何变量,可以运行任何函数,并且仍然可以在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;
?>

脚本:

<?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包含在其缓冲区中,运行任何函数/方法,并在此过程中分配任何变量。然后,您只需将缓冲区的内容记录到一个变量中,并根据需要使用它

这样一来,如果你不想在那一秒将其回传到页面上,你就不必了。在输出字符串之前,可以循环并不断添加到字符串中

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

试试这个(作为全局变量,或者在需要时实例化):


现在,任何函数调用都要经过
$fn
实例。因此,现有函数
testfunction()
可以在herdoc中使用
{$fn->testfunction()}


基本上,我们将所有函数包装到一个类实例中,并使用PHP的
\u call magic
方法将类方法映射到需要调用的实际函数。

大家应该注意,它也适用于双引号字符串


有趣的提示。

此代码段将使用userscope中已定义函数的名称定义变量,并将它们绑定到包含相同名称的字符串。让我示范一下

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;
函数add($int){return$int+1;}
$f=获取定义的函数();foreach($f[user]作为$v){$$v=$v;}
$string=有点晚了,但仍然是。
这在heredoc中是可能的


我认为使用herdoc生成HTML代码非常好。例如,我发现以下内容几乎完全不可读

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

但是,为了实现简单性,您必须在开始之前评估函数。我不认为这是一个如此糟糕的约束,因为这样做,最终会将计算与显示分离,这通常是一个好主意

我认为以下内容很容易理解:

$page_content = getPageContent();

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

打印如果您确实想这样做,但比使用您可以使用的类要简单一些:

function fn($data) {
  return $data;
}
$fn = 'fn';

$my_string = <<<EOT
Number of seconds since the Unix Epoch: {$fn(time())}
EOT;
函数fn($data){
返回$data;
}
$fn='fn';

$my_string=这里是一个使用@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>";
双功能($i)
{返回$i*2;}
三重功能($i)
{返回$i*3;}
$tab='double';
echo“{$tab(5)}是$tab 5
”; $tab='triple'; echo“{$tab(5)}是$tab 5
”;

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

您忘记了lambda函数:

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

echo在这里找到了具有包装功能的不错的解决方案:

函数heredoc($param){
//只要把传给我们的东西还给我们就行了
返回$param;
}
$herdeoc='herdeoc';

$string=为了完整起见,您还可以使用
${'}
黑魔法:


echo
这在今天的PHP7.x上更优雅了一点

<?php

$test = function(){
    return 'it works!';
};


echo <<<HEREDOC
this is a test: {$test()}
HEREDOC;

这是一个很好的解决方案,适用于不能只向现有项目添加模板引擎的情况。谢谢,我现在正在使用它。当性能非常关键时,不应该广泛使用它:我已经读过好几次了,
call\u user\u func\u array
,上次在php.net的评论中:不错!我喜欢它,为什么我没想到这个?!?:-)我已经在第一个例子中使用了这种语法;它的缺点是先将函数名放入变量中,然后才能在herdeoc部分的花括号内调用它,这是
<?php
echo <<<ETO
<h1>Hellow ETO</h1>
ETO;
<div><?=<<<heredoc
Use heredoc and functions in ONE statement.
Show lower case ABC="
heredoc
. strtolower('ABC') . <<<heredoc
".  And that is it!
heredoc
?></div>
<?php

$test = function(){
    return 'it works!';
};


echo <<<HEREDOC
this is a test: {$test()}
HEREDOC;