nowdoc中变量不被解析,其本质是原样输出的字符串字面量,仅识别'和\两个转义,其余如$user等变量名均按字面显示。

nowdoc 里变量根本不会被解析
PHP 的 nowdoc 本质是「原样输出的字符串字面量」,和单引号字符串一样,它不解析任何变量、转义序列(除了 ' 和 \)。你写 $name,它就原封不动当字符显示,不是取值。
常见错误现象:
— 代码里写了 $user = 'Alice'; echo ,结果输出是 <code>Hello $user,不是 Hello Alice
— 误以为 nowdoc 像 heredoc 那样支持插值,结果调试半天发现变量根本没展开
- 使用场景:适合写 SQL 模板、正则表达式、配置片段、HTML 片段等需要保留原始符号、又不想被变量干扰的内容
- 如果真要插值,必须换用
heredoc(去掉开头的单引号),但要注意:heredoc 会解析$var、${var}、$arr[key],但不解析函数调用或复杂表达式 - 性能上,
nowdoc略快于heredoc,因为 PHP 不做任何解析,但差异微乎其微,别为这点优化改逻辑
想在 nowdoc 里用变量?只能拼接
没有绕过规则的办法,PHP 就是这么设计的。你要让变量生效,就得把 nowdoc 当作静态模板的一部分,再用字符串拼接或 sprintf() 注入值。
示例:
立即学习“PHP免费学习笔记(深入)”;
所谓数组,就是相同数据类型的元素按一定顺序排列的集合,就是把有限个类型相同的变量用一个名字命名,然后用编号区分他们的变量的集合,这个名字称为数组名,编号称为下标。组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。数组是在程序设计中,为了处理方便, 把具有相同类型的若干变量按有序的形式组织起来的一种形式。这些按序排列的同类数据元素的集合称为数组。 数组应用&二维数组目录 1. 数组的简单应用2. 数组排序3. 数组查找4. 数组的使用思想5. 查表法6. 二维数组7. 数组综合
echo 'User: ' . $user . <<<'EOT' — logged in at: %s — IP: %s EOT; // 注意:nowdoc 内部仍是纯文本,%s 是留给 sprintf 用的占位符,不是 PHP 解析的
- 推荐组合:用
nowdoc写固定结构,用sprintf()或strtr()替换占位符,比全用heredoc更可控(避免意外解析) - 别用
eval()或preg_replace_callback()去“动态解析” nowdoc —— 安全风险高、可读性差、维护成本爆炸 - 注意拼接时的类型:若
$user是null或array,直接拼接会触发警告,建议提前(string)$user或用strval()
heredoc 和 nowdoc 的边界容易混淆
区别只在开始标记的单引号:有单引号是 nowdoc,没单引号是 heredoc。但很多人写 却以为它是 nowdoc,其实不是 —— 必须是 <code> 才生效。
- 错误写法:
→ 这是 <code>heredoc,$id会被解析(可能出错或注入) - 正确 nowdoc:
→ <code>$id原样保留 - 兼容性:两者从 PHP 5.3 起都支持,无需担心低版本;但注意 nowdoc 的标识符不能含空格或特殊字符,否则解析失败报
Parse error: syntax error, unexpected end of file
多行 SQL 或配置用 nowdoc 最稳妥
比如写一个带注释、缩进、多行条件的 SQL 查询,用 nowdoc 可以完全避免引号转义、变量干扰、换行混乱等问题。
示例:
立即学习“PHP免费学习笔记(深入)”;
$sql = <<<'SQL' SELECT u.name, u.email, COUNT(o.id) AS order_count FROM users u LEFT JOIN orders o ON u.id = o.user_id WHERE u.status = 'active' GROUP BY u.id ORDER BY order_count DESC LIMIT 10; SQL;
- 这种写法下,SQL 里的所有符号(单引号、双引号、$ 符号、反斜杠)都不用额外转义
- 如果你在 SQL 中真需要插入变量,建议用 PDO 预处理,而不是在字符串里拼 —— nowdoc + prepare 是黄金组合
- 容易被忽略的一点:nowdoc 结束标识符必须顶格、独占一行、后面不能有任何空白字符(包括空格、制表符),否则 PHP 会继续读取直到找到真正匹配的结尾,导致意外截断或解析错误










