PHP 项目做到一定规模,必然会在多个页面里用到相同的头部导航、底部版权、数据库配置、公共函数库。逐页复制粘贴不仅低效,出错后维护成本极高。PHP 的文件包含机制正是用来应对这个问题的,让一段代码或 HTML 片段定义一次,处处引用。
include 和 require 的基本认知
PHP 提供两套文件包含语句:include 和 require。二者语法几乎一样,功能都是把目标文件的内容插入到当前脚本的包含位置。
它们的语法有两种写法,带不带括号都行:
include 'header.php';
include ('header.php');
require 'config.php';
require ('config.php');
这两种语句在成功加载文件时表现一致。差异只在文件找不到或加载失败时的处理方式上,这个差异决定了它们在项目里的不同适用场景。
PHP include:警告后继续执行
include 在目标文件缺失时,只会抛出一个 E_WARNING 级别的警告,脚本其余部分照常运行。这种“温柔”的失败处理机制,让 include 适合加载那些非关键性的内容模块。
先看一个最基础的应用——把导航菜单独立成公用文件,然后在主页面中引用。
菜单文件 menu.html:
<a href="index.php">首页</a> |
<a href="course.php">课程中心</a> |
<a href="about.php">关于我们</a>
主页文件 index.php:
<?php include 'menu.html'; ?>
<h1>欢迎来到编程实训平台</h1>
<p>这里有系统的 PHP 教程供你学习。</p>
输出效果是菜单的导航链接紧跟着页面主体内容,访问者看到的是一个完整的页面。
再比如底部版权信息,网站所有页面都要展示,把它提取到 footer.html:
<p>Copyright 2026 - 编程实训平台 版权所有。</p>
然后在任意页面里引用:
<?php include 'footer.html'; ?>
<p>感谢你的访问,有任何疑问请联系 alan@ebingou.cn。</p>
即使有一天 footer.html 被误删了,include 也只会甩一个警告,网站其余内容仍然正常显示。用户可能看不到版权行,但主功能区不受影响。这个特性让 include 在处理非核心模块时表现得很稳妥。
PHP require:出错即停的强制依赖
require 的行为比 include 严格得多。目标文件缺失时,它会触发 E_COMPILE_ERROR 致命错误,脚本当场中止执行。听起来很“”,但对于项目的关键依赖来说,这正是需要的行为——依赖没了,继续跑下去可能产生更大的问题。
最典型的使用场景是数据库配置文件。假设 db_config.php 存放数据库连接参数:
<?php
$dbHost = 'localhost';
$dbUser = 'root';
$dbPass = '';
$dbName = 'course_platform';
?>
在需要数据库操作的页面中用 require 引入:
<?php require 'db_config.php'; ?>
<p>数据库连接参数已加载,正在进行后续操作。</p>
数据库配置文件缺失意味着后续的所有数据库操作都会失败,与其让脚本带着未定义的变量继续跑出一堆错误,不如在源头就停下来。require 的严格性在这里是一种保护。
公共函数库也是同样的道理。假设 function_lib.php 定义了项目里用到的核心函数:
<?php
function showGreeting($name) {
return "你好," . $name . ",欢迎学习 PHP!";
}
?>
调用方用 require 引入:
<?php require 'function_lib.php'; ?>
<p><?php echo showGreeting('小明'); ?></p>
如果 function_lib.php 缺失,调用 showGreeting() 会触发未定义函数错误,影响范围不可控。require 把问题前置,在加载阶段就暴来。
实际行为对比:看得见的差异
假设有个页面逻辑是先输出一句“程序启动”,然后包含一个不存在的文件,之后再输出一句话。include 和 require 会呈现不同的结果。
用 include 的情况:
<?php
echo "程序启动<br>";
include "not_exist.php";
echo "这条信息你还能看到。";
?>
浏览器会输出“程序启动”,接着显示一行警告说明文件没找到,之后仍然输出“这条信息你还能看到”。三个步骤全部执行了。
换成 require:
<?php
echo "程序启动<br>";
require "not_exist.php";
echo "这条信息你看不到。";
?>
输出“程序启动”后,紧跟着致命错误提示,脚本立即终止,“这条信息你看不到”不会出现在页面上。
有一次我重构一个老项目,某个模块的用户头像上传功能偶尔失效,排查半天发现是模板里用 include 引入了一个可选的缩略图生成脚本。那脚本因为依赖的 GD 库没装而导致包含失败,但因为用的是 include,PHP 只是静默警告,页面其他部分照常渲染,问题藏了很久。后来我把这类可选依赖全改成 include,核心依赖全部用 require,出问题时错误级别就能直接暴露问题所在。
相对路径与绝对路径的选择
不管是 include 还是 require,指定文件路径时可以用相对路径也可以用绝对路径。相对路径以当前执行脚本所在目录为基准,目录结构复杂时容易出问题。绝对路径则从文件系统的根开始定位。
实际工作中,我更习惯用 __DIR__ 魔术常量拼出基于当前文件位置的绝对路径:
include __DIR__ . '/includes/header.php';
require __DIR__ . '/../config/db_config.php';
__DIR__ 始终指向包含这段代码的文件所在目录,不受 include_path 配置和脚本运行目录的影响,可靠度比相对路径高不少。写可移植的项目时,这个习惯很受用。
本节课程知识要点
include 和 require 的选择,本质上是对“缺失依赖的容忍度”的权衡。非关键内容区块(侧边栏、广告位、友情链接等),用 include,缺失时只警告不中断,页面主体功能继续运转。关键依赖(数据库配置、核心函数库、安全校验脚本等),用 require,缺失时直接中止,防止带着隐患继续执行。路径写法上建议使用 __DIR__ 拼接绝对路径,避免相对路径在多层目录嵌套时带来的不确定性。另外 PHP 还有 include_once 和 require_once,它们在相同文件已被包含时自动跳过,防止函数重复定义和变量覆盖问题,引入函数库时通常优先用 require_once。
文件包含让 PHP 项目从“一堆独立的脚本”真正变成“有组织结构的应用”。把重复代码提取成公用文件,改一处就全局生效,开发和维护负担都大幅下降。