nowdoc 中的 $name 不会被解析,因其本质是原样字符串,与单引号字符串相同,完全跳过变量解析,如 $user['id'] 或 $$var 均按字面量输出。

nowdoc 里写 $name 不会解析变量
PHP nowdoc 的本质是「原样字符串」,和单引号字符串一样,完全跳过变量解析。哪怕你写了 $user['id'] 或 $$var,它就只是七个字符、十个字符——PHP 一字不碰。
常见错误现象:复制了一段带变量的 SQL 或 HTML 模板进 nowdoc,结果输出里直接看到 $title 字样,而不是实际值。
- nowdoc 语法必须以
开头,结尾的 <code>IDENTIFIER必须顶格、无空格、无缩进 - 标识符不能是 PHP 关键字(比如
class、function),否则 parse error - 结尾标识符后不能跟任何字符(包括空格、制表符、注释),否则会被当成内容的一部分
想插变量?得换 heredoc 或拼接
nowdoc 不支持变量不是缺陷,是设计选择——它要的就是「零解释、可预测、适合嵌入大段原始文本」。真要插值,两个靠谱路子:
- 改用 heredoc:
,里面可以写 <code>$name、{$user['email']},但注意缩进会影响输出(heredoc 会保留换行和空格) - nowdoc +
str_replace()或printf():先把占位符(比如{{name}})放进 nowdoc,再用函数替换,控制力更强,也更安全(避免意外变量注入)
示例:
立即学习“PHP免费学习笔记(深入)”;
$template = <<<TEMPLATE
<h2>{{title}}</h2>
<p>{{content}}</p><div class="aritcle_card flexRow">
<div class="artcardd flexRow">
<a class="aritcle_card_img" href="/ai/1473" title="AI Background Remover"><img
src="https://img.php.cn/upload/ai_manual/000/000/000/175680148858617.png" alt="AI Background Remover" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a href="/ai/1473" title="AI Background Remover">AI Background Remover</a>
<p>AI背景移除工具,免费使用</p>
</div>
<a href="/ai/1473" title="AI Background Remover" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a>
</div>
</div>
TEMPLATE;
echo str_replace(['{{title}}', '{{content}}'], [$title, $content], $template);
nowdoc 和 heredoc 的关键区别在首行标识符后有没有引号
这是最常被忽略的语法分水岭:
→ nowdoc(单引号包裹标识符),不解析变量,不转义 <code>\n\t→ heredoc(无引号),解析变量,转义反斜杠序列
注意:PHP 7.3+ 允许在 heredoc/nowdoc 中省略结尾分号后的换行,但老版本仍要求严格换行;如果迁移旧代码,检查 Parse error: syntax error, unexpected end of file 很可能就是 nowdoc 结尾多了一个空格。
嵌入 JSON 或 JS 代码时 nowdoc 更稳
当你要输出一段含大量 $、{}、\ 的 JSON 配置或内联 JS,nowdoc 是首选——不用反复加反斜杠逃逸,也不怕变量名撞上数据字段名。
例如生成一个带用户 ID 的初始化脚本:
$js = <<<'JS'
window.APP.init({
userId: 123,
token: "$2y$10$abc", // 这里的 $ 不会被当变量
config: { mode: "dev" }
});
JS;
换成 heredoc 就得写 \$2y\$10\$abc,一不小心漏掉一个反斜杠,JSON 就失效了。
容易被忽略的是:nowdoc 的标识符本身不能含特殊字符,但内容里可以任意放 HTML 标签、SQL 关键字、甚至 PHP 代码片段——只要不触发结尾标识符匹配,它就纯粹是“一块字节流”。










