PHP include 和 require 语句

PHP include 和 require 语句中文讲解

什么是 include 和 require 语句?

includerequire 是 PHP 中用于在脚本中引入外部文件的语句。它们允许开发者将代码模块化,将公共代码(如配置、函数、类或 HTML 片段)存储在单独文件中,并在需要时引入。两者功能类似,但错误处理方式不同,适合在 Web 开发中复用代码或组织项目结构。

为什么使用 include 和 require?

  • 代码复用:避免重复编写相同代码,如页眉、页脚或数据库连接。
  • 模块化:将代码分解为独立文件,便于维护和协作。
  • 组织性:结合命名空间和目录结构,清晰管理大型项目。
  • 典型场景:加载配置文件、模板、函数库或类文件。

基本语法

include 'filename.php';
require 'filename.php';
  • filename:要引入的文件路径(相对或绝对路径)。
  • 变体
  • include_once:确保文件只引入一次。
  • require_once:类似 include_once,但使用 require 的错误处理机制。

include vs require

  • 错误处理
  • include:文件不存在或无法加载时,触发警告(Warning),脚本继续执行。
  • require:文件不存在或无法加载时,触发致命错误(Fatal Error),脚本终止。
  • 使用场景
  • include:适合非关键文件(如可选模板),允许脚本在文件缺失时继续运行。
  • require:适合关键文件(如数据库配置),文件缺失会导致功能失效。
  • 性能:两者性能差异微小,但 *_once 变体会检查文件是否已引入,略增加开销。

基本示例

  1. 使用 include
    假设有一个文件 header.php
   <!-- header.php -->
   <header>
       <h1>欢迎来到我的网站</h1>
   </header>

主文件 index.php

   <?php
   include 'header.php';
   echo "这是页面内容";
   ?>

输出:

   <header>
       <h1>欢迎来到我的网站</h1>
   </header>
   这是页面内容
  1. 使用 require
    配置文件 config.php
   <?php
   define('DB_HOST', 'localhost');
   define('DB_USER', 'user');
   define('DB_PASS', 'pass');
   ?>

主文件 db_connect.php

   <?php
   require 'config.php';
   $pdo = new PDO("mysql:host=" . DB_HOST, DB_USER, DB_PASS);
   ?>
  1. 使用 include_once/require_once
    防止重复引入导致的重定义错误:
   <?php
   // functions.php
   function sayHello() {
       echo "Hello!";
   }
   ?>
   <?php
   include_once 'functions.php';
   include_once 'functions.php'; // 不会重复引入
   sayHello(); // 输出:Hello!
   ?>

结合表单处理示例

以下是一个使用 includerequire 处理表单的完整示例,展示模块化代码结构。

  1. 配置文件 (config.php):
   <?php
   // 数据库配置
   define('DB_HOST', 'localhost');
   define('DB_NAME', 'test');
   define('DB_USER', 'user');
   define('DB_PASS', 'pass');
   ?>
  1. 数据库连接 (db.php):
   <?php
   require 'config.php'; // 必须加载配置
   try {
       $pdo = new PDO("mysql:host=" . DB_HOST . ";dbname=" . DB_NAME, DB_USER, DB_PASS);
       $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
   } catch (PDOException $e) {
       die("数据库连接失败: " . $e->getMessage());
   }
   ?>
  1. HTML 表单 (form.html):
   <!DOCTYPE html>
   <html lang="zh-CN">
   <head>
       <meta charset="UTF-8">
       <title>用户注册</title>
       <style>
           .error { color: red; }
           label { display: inline-block; width: 100px; }
           input { margin-bottom: 10px; }
       </style>
   </head>
   <body>
       <h2>用户注册</h2>
       <?php include 'errors.php'; // 包含错误显示 ?>
       <form action="process.php" method="post">
           <?php
           session_start();
           if (empty($_SESSION['csrf_token'])) {
               $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
           }
           ?>
           <input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($_SESSION['csrf_token']); ?>">
           <label for="name">姓名*:</label>
           <input type="text" id="name" name="name" value="<?php echo isset($_POST['name']) ? htmlspecialchars($_POST['name']) : ''; ?>">
           <br>
           <label for="email">邮箱*:</label>
           <input type="email" id="email" name="email" value="<?php echo isset($_POST['email']) ? htmlspecialchars($_POST['email']) : ''; ?>">
           <br>
           <input type="submit" value="注册">
           <p>* 表示必需字段</p>
       </form>
   </body>
   </html>
  1. 错误显示文件 (errors.php):
   <?php
   if (!empty($errors)) {
       echo "<div class='error'><ul>";
       foreach ($errors as $error) {
           echo "<li>$error</li>";
       }
       echo "</ul></div>";
   }
   ?>
  1. 处理脚本 (process.php):
   <?php
   session_start();
   $errors = [];

   if ($_SERVER['REQUEST_METHOD'] === 'POST') {
       // 验证 CSRF 令牌
       if (!isset($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) {
           $errors[] = "CSRF 验证失败";
       } else {
           // 清理输入
           $name = trim($_POST['name'] ?? '');
           $email = trim($_POST['email'] ?? '');

           $name = filter_var($name, FILTER_SANITIZE_STRING);
           $email = filter_var($email, FILTER_SANITIZE_EMAIL);

           // 验证
           if (empty($name)) {
               $errors[] = "姓名是必需字段";
           }
           if (empty($email)) {
               $errors[] = "邮箱是必需字段";
           } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
               $errors[] = "无效的邮箱格式";
           }

           // 如果没有错误,保存数据
           if (empty($errors)) {
               require 'db.php'; // 加载数据库连接
               try {
                   $stmt = $pdo->prepare("INSERT INTO users (name, email) VALUES (:name, :email)");
                   $stmt->execute(['name' => $name, 'email' => $email]);
                   echo "注册成功!";
                   $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
                   exit;
               } catch (PDOException $e) {
                   $errors[] = "数据库错误: " . $e->getMessage();
               }
           }
       }
   }

   // 显示表单和错误
   include 'form.html';
   ?>
  1. 数据库表结构 (users 表):
   CREATE TABLE users (
       id INT AUTO_INCREMENT PRIMARY KEY,
       name VARCHAR(255) NOT NULL,
       email VARCHAR(255) NOT NULL UNIQUE,
       created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
   );

关键点解析

  • 模块化config.php(配置)、db.php(数据库连接)、errors.php(错误显示)分离代码,提高可维护性。
  • include vs require
  • 使用 require 'config.php'require 'db.php',因为数据库连接是关键功能,失败应终止脚本。
  • 使用 include 'errors.php'include 'form.html',因为错误显示和表单是可选的,失败不影响核心逻辑。
  • 安全性
  • htmlspecialchars() 防止 XSS。
  • PDO 预处理语句防止 SQL 注入。
  • CSRF 令牌防止跨站请求伪造。
  • 错误处理:集中存储错误,统一显示,结合 include 回显表单。

路径处理

  • 相对路径:如 include 'header.php',基于当前文件位置。
  • 绝对路径:使用 __DIR__ 确保路径正确:
  include __DIR__ . '/includes/header.php';
  • 文件不存在
  • include:触发警告,继续执行。
  • require:触发致命错误,停止执行。
  include 'nonexistent.php'; // 警告,继续
  require 'nonexistent.php'; // 致命错误,停止

最佳实践

  • 选择合适的语句
  • require 加载关键文件(如数据库配置)。
  • include 加载非关键文件(如模板)。
  • *_once 防止重复引入(如函数库)。
  • 路径管理:使用 __DIR__ 或自动加载(PSR-4)避免路径问题。
  • 错误检查:检查文件是否存在:
  if (file_exists('config.php')) {
      require 'config.php';
  } else {
      die("配置文件缺失");
  }
  • 模块化设计:将功能拆分为独立文件,结合命名空间和 Composer。
  • 安全性:清理用户输入,防止注入攻击。

参考资源

总结

includerequire 是 PHP 实现代码复用和模块化的核心工具,require 适合关键依赖,include 适合可选内容。结合 *_once 防止重复引入,使用 __DIR__ 确保路径正确,可以构建清晰、安全的 Web 应用。上述示例展示了如何将 includerequire 应用于表单处理,涵盖验证、数据库交互和安全性,适合实际开发场景。

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注