写在前面:这是 2013 年前后,博客圈几乎每本 PHP 入门教程都会讲的一节。那时候没有 Composer,没有框架全家桶,一个站就是一个 index.php 从头写到尾——而 include 与 require,就是老 PHP 开发者第一次接触”代码复用”的地方。
为什么需要 include
写 PHP 最大的痛点是:每个页面都要重复输出头部、底部、数据库连接。用 include 可以把公共代码抽出来,改一处,全站生效。
<?php
// header.php —— 每个页面的公共头部
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title><?php echo $page_title; ?></title>
</head>
<body>
<?php
// 每个页面只需:
$page_title = '我的老站';
include 'header.php';
?>
include 与 require 的区别
这是每个老 PHP 面试都会问的题:
| 函数 | 文件不存在时 | 使用场景 |
|---|---|---|
include | 只给警告,脚本继续执行 | 可选模块(如广告位、统计代码) |
require | 致命错误,脚本停止 | 必须存在的依赖(如配置文件) |
<?php
// 配置文件丢失,全站必须停机排查,用 require
require 'config.php';
// 页脚统计代码丢了无所谓,用 include
include 'footer.php';
?>
include_once / require_once
当你把文件拆得多了,很容易重复引入同一个文件——函数重定义就会致命错误。
<?php
// 用 _once 变体,重复引入会被自动忽略
require_once 'db.php';
require_once 'db.php'; // 不会报错
?>
经验法则:类、函数的定义文件用 require_once;模板片段用 include。
作用域的坑
这是老项目里最常见的隐蔽 bug:include 进来的文件里,变量共享的是当前作用域。
<?php
$db_host = 'localhost';
include 'db_config.php';
// db_config.php 里可以直接使用 $db_host,也能修改它
?>
函数内部的 include 则不同——文件里的变量只在函数内有效:
<?php
function load_config() {
include 'config.php'; // $config 只在这里有效
return $config;
}
$config = load_config();
?>
安全提醒
老项目最忌讳的就是把用户输入拼进 include 路径:
<?php
// 危险!$page 来自 $_GET 时,可被用于任意文件读取
include $_GET['page'] . '.php';
?>
正确的做法是白名单:
<?php
$pages = ['home' => 'home.php', 'about' => 'about.php'];
$page = isset($_GET['page']) ? $pages[$_GET['page']] : 'home.php';
include $page;
?>
小结
require用于必须的文件,include用于可选的片段- 类、函数定义用
require_once,避免重复定义 include里的变量受当前作用域影响,注意区分函数内外- 永远不要把用户输入直接拼进 include 路径