include语句本身不输出内容,但被包含文件的空白字符(如换行、空格、bom)会被原样输出,导致页面出现多余空白;需删bom、去结尾换行、避免?>后换行、禁用纯空行。

include 语句本身不会输出内容,但被包含文件的空白字符会
PHP 的 include 只是把目标文件的内容“原样插入”到当前执行位置。它不自动 trim、不忽略换行、不过滤空格——哪怕被包含的 PHP 文件开头或结尾多了一个换行符,浏览器就会渲染出一个空行。
常见现象:页头 include('header.php') 后, 里第一行就空着;或者页脚引入后,页面底部多出一行空白。
- 检查
header.php文件末尾是否有多余的?>后换行(即?>\n)——这是最常见源头 - 确认该文件保存为 UTF-8 无 BOM 格式;带 BOM 的 UTF-8 会在开头隐式插入
\xEF\xBB\xBF,PHP 会原样输出,浏览器解析为乱码或空白 - 用十六进制编辑器或命令行
xxd header.php | head -5查看开头是否有ef bb bf
PHP 输出缓冲未开启时,HTML 换行直接透出到响应体
当没调用 ob_start(),PHP 会边解析边输出。如果 include 前后有 HTML 换行、缩进,或被包含文件里有纯文本换行(比如 <?php ... ?>\n<div>),这些换行都会成为 HTTP 响应的一部分。
<p>这不是 bug,是 PHP 的默认行为:它不负责美化 HTML 结构,只负责执行和拼接。</p>
<ul>
<li>在主脚本顶部加 <code><?php ob_start(); ?>,结尾加 <?php ob_end_flush(); ?>,可统一控制输出
<?php 开头、不写 ?> 结尾(即“纯 PHP 文件”,无混合 HTML)
<?php include('header.php'); ?><div>...</div> 这种紧贴写法,避免换行符落入响应流require_once / include_once 不解决空白问题,只防重复定义
很多人误以为换用 include_once 能“智能去重空白”,其实它只保证文件不被二次加载,对文件内容里的空格、换行、BOM 完全无感。
访问全球海洋潮汐模型。功能包括查询指定日期、时间和地点的潮高、潮汐极值及格点天气数据。
它和 include 在输出行为上完全一致——区别仅在于是否检查已加载列表。
-
include和include_once都可能输出多余空白;require和require_once同理 - 如果你发现换用
_once后空白消失,大概率是因为第二次包含被跳过,而第一次包含的文件本身被你顺手修好了 - 别依赖
_once掩盖输出问题;它解决的是逻辑错误(如重复声明函数),不是呈现问题
模板引擎或框架里仍要警惕原始 include
即使你在用 ThinkPHP、Laravel 或 Twig,只要底层还用 include 加载局部视图(比如 include('_nav.php')),上面所有规则依然生效。
框架的“模板继承”或“组件化”机制只是封装了逻辑,没改 PHP 解析器的行为。
- ThinkPHP 的
{:include('header')}最终仍调用include,空白来源相同 - Laravel 的
@include('partials.header')底层也是include,除非你启用了 Blade 编译缓存且开启了优化选项(如去除空白) - 真正可靠的解法永远落在文件内容本身:删 BOM、去结尾换行、避免
?>、不用纯空行分隔逻辑块
footer.php 最后一行的 ?> 后面,或 config.php 开头的 BOM 里,不动声色地撑开整个页面的垂直间距。










