有了像 JavaScript 中的 模板字面量 和 JSX 等模板语言,我已经习惯了想要将我的 HTML 模板写成一个漂亮的块,并在需要的地方撒上变量。
前几天我遇到了一种情况,需要在“原始”PHP 中这样做,所以我只是在这里记录一下。
假设我有一些像这样的数据…
$title = "The Title";
$desc = "Some information about this thing blah blah.";
$img = "/images/header.jpg";
但是这些数据会发生变化,或者可能有多组数据,我想能够将这些数据传递给一个函数,并让它吐出一些 HTML。这样,就可以轻松地更改模板,并使其影响到所有使用它的位置。
我不想 将它散布到一些 HTML 中 作为一次性操作。我更希望有一个函数。
function echo_card($title = "Default Title", $desc = "Default Description", $img = "/images/fallback.jpg") {
echo "";
}
PHP 并没有像 JavaScript 模板字面量那样将一堆 HTML 字符串插值在一起,而是有 HEREDOC 语法,它有点类似于 JavaScript 的模板字面量。
function echo_card($title = "Default Title", $desc = "Default Description", $img = "/images/fallback.jpg") {
$html = <<<"EOT"
<div class="card">
<img src="$img" alt="">
<h2>$title</h2>
<p>$desc</p>
</div>
EOT;
echo $html;
}
现在,我可以调用此函数来使用我的数据回显 HTML 模板。
echo_card($title, $desc, $img);
我发现这是一种相当舒适的工作方式,不需要任何其他库或任何东西。
很高兴知道。谢谢你的分享!
太棒了,对我来说非常有用,谢谢,新年快乐
您真的写了一篇推广将未转义的字面量包含到 HTML 标记中的文章吗? 在 (几乎) 2020 年?!
这些模板引擎的存在是有原因的,一个非常好的原因——提供安全性和便利性。您在这里发布的是一个如何编写 XSS 漏洞 PHP 的示例,这几乎是在每个人(最终)学会如何做相反的事情十年后!
您应该删除它,或者正确地进行操作(届时您将亲身体验模板引擎存在的原因)
是的!而且,我还在生产网站上发布了它!!! 人性啊!!!
我不想使用模板引擎。我有我的理由。
在我的例子中,情况并非如此。它没有获取用户输入。它没有获取除了我自己用手工编写的代码传递给它的某些字符串之外的任何东西,我这样做只是为了易用性。一个简单的抽象。
但是,XSS 是值得一提的,所以我将更新这篇文章以反映这一点。
您可能需要考虑在某些时候使用
htmlspecialchars()
来输出变量,以便对所有字符进行 HTML 编码。否则,像>
这样的字符可能会破坏您的模板,或者使您容易受到 HTML 注入的攻击。这很好,但可能更有用:将您的模板放在一个文件夹中,例如 {TEMPLATE_DIR}/card.php,然后使用类似 template('card', $atts) 的函数包含它。
模板函数如下所示
而模板文件
这种方式更现实,因为大多数时候您需要在代码中进行一些逻辑,而 HEREDOC 语法可能会使这变得困难。
顺便说一句,如果您仍然想要使用这种方法,您应该考虑只使用一个 $atts 参数,这样您就可以轻松地进行开发,而无需考虑参数的顺序和名称。例如,WordPress 有许多参数名为 $depracated。我认为,您可以通过始终使用 $atts 数组来防止这种情况。
回显 HEREDOC 变量是一件很酷的事情,但它有很大的局限性,特别是如果您需要根据您拥有的数据进行一些检查 (if),例如,如果您需要根据数据添加类或样式,那么您就不能在 HEREDOC 中包含“if”或调用函数,但如果您直接从函数中回显您的 html,则可以这样做
function echo_card($title = “Default Title”, $desc = “Default Description”, $img = “/images/fallback.jpg”) {
?>
<img src="” alt=””>
<h2 >
<?
}
我一直使用以下方法而不是使用 HEREDOC,这样做是不正确或不建议的吗?
function whatever($var = 'default') {
?>
<div class="blah"><?= $var ?></div>
<?php
}
嘿!这太棒了!我以前从未见过 EOT 方法这样使用。太聪明了!
我还有一个使用纯 PHP 为我的应用程序实现此功能的方法。
这是一个例子
你好世界!
<?php
}
这在应用程序中的语法高亮方面非常有帮助,并且仍然输出 html!
在 HEREDOC 中使用变量时,请考虑使用 ${variable}。这样可以更容易地区分 HEREDOC 中的变量。:)
您可以直接输出 HTML,而不是使用临时变量的内存开销。
注意,需要根据变量的输出位置对其进行上下文转义。换句话说,
htmlspecialchars()
。我知道我不是第一个指出这一点的人,但这真的很重要。值需要在输出之前进行适当的转义。即使变量不是来自用户,并且攻击者无法修改它们,不转义它们仍然是一个错误,因为它们可能包含特殊字符。
您应该使用
htmlspecialchars
(或 WordPress 代码的esc_html
或esc_attr
)。不幸的是,这会让整个事情看起来更难看,但这就是 PHP 的特性。PHP-CS 可以自动检测到很多这类问题。
我不喜欢这种做法,因为它强迫负责集成的人员修改此代码——并且可悲地会导致一些意想不到的错误。相反,为什么不使用带有 ob_start/ob_end 组合的 php 函数 include 呢? 优点是 html + php 会导出到另一个文件。