Avatar ·

Чем отличаются require, include, require_once и include_once в PHP?

Всем привет! Я только начал изучать PHP и никак не могу разобраться с подключением файлов. В учебниках и на форумах постоянно встречаю четыре конструкции: require, include, require_once и include_once. На первый взгляд они делают одно и то же — вставляют код из другого файла, но я чувствую, что между ними есть важные различия.

Вот пример моего кода. У меня есть файл config.php с настройками базы данных:

<?php
$host = 'localhost';
$user = 'root';
$pass = 'password';
?>

И основной файл index.php, где я пытаюсь его подключить:

<?php
include 'config.php';
echo $host; // Работает
?>

Но когда я меняю include на require, поведение вроде бы такое же. А если файла не существует, то include просто показывает ошибку, а require — останавливает скрипт. И что за _once версии? Когда их использовать? Я пытался подключить файл дважды через include и получил дублирование функций, что вызвало фатальную ошибку.

Объясните пожалуйста подробно: в каких ситуациях какой вариант лучше применять? И есть ли разница в производительности?

<<>>

Главное различие: фатальная ошибка vs предупреждение

Ключевое отличие между require и include — реакция на отсутствие файла:

  • require — если файл не найден, скрипт немедленно завершается с фатальной ошибкой (E_COMPILE_ERROR).
  • include — выдаёт предупреждение (E_WARNING), но скрипт продолжает выполнение.

Пример с несуществующим файлом:

<?php
// include — скрипт продолжит работу
include 'missing.php'; // Warning: include(missing.php): failed to open stream
echo "Этот текст будет выведен"; 

// require — скрипт остановится
require 'missing.php'; // Fatal error: require(): Failed opening required 'missing.php'
echo "Этот текст НЕ будет выведен";
?>

Когда использовать require, а когда include?

  • require — для критически важных файлов, без которых работа приложения невозможна. Например: конфигурация БД, ядро фреймворка, классы автозагрузчика.
  • include — для необязательных компонентов. Например: шаблоны, виджеты, рекламные баннеры. Если файл не загрузился, страница просто отобразится без этого блока.

Варианты с _once: защита от повторного подключения

require_once и include_once делают то же самое, что и их базовые версии, но с одним важным дополнением — они проверяют, был ли файл уже подключён ранее. Если да, то повторное подключение игнорируется.

Проблема без _once:

<?php
// functions.php
function sayHello() {
    echo "Привет!";
}

// index.php
include 'functions.php';
include 'functions.php'; // Fatal error: Cannot redeclare sayHello()
?>

Решение с _once:

<?php
include_once 'functions.php';
include_once 'functions.php'; // Второй раз проигнорируется — ошибки нет
sayHello(); // Работает
?>

Когда использовать _once?

  • require_once — для классов, функций, конфигураций, которые должны быть объявлены только один раз. Это стандарт для ООП-проектов.
  • include_once — для шаблонов или библиотек, которые могут быть вызваны из разных мест, но не должны дублироваться.

Производительность

Варианты с _once немного медленнее, так как PHP хранит список уже подключённых файлов и проверяет его при каждом вызове. В современных версиях (7.4+) разница минимальна — менее 0.001 секунды на 1000 вызовов. Для реальных проектов этим можно пренебречь.

Практические рекомендации

  1. Для классов и функций всегда используйте require_once — это предотвратит ошибки дублирования.
  2. Для конфигурационных файлов (БД, пути) — require или require_once — зависит от архитектуры. Если конфиг может быть подключён только один раз — require_once.
  3. Для шаблонов HTML, которые могут повторяться — include или include_once. Если шаблон гарантированно уникален — include быстрее.

Пример правильного использования:

<?php
// Критичные компоненты
require_once 'vendor/autoload.php';
require_once 'config/database.php';

// Шаблоны
include 'header.php';

$content = getPageContent();
echo $content;

include 'footer.php'; // footer может быть подключён из другого места
?>

Итог: require — "умри, если нет файла", include — "попробуй, но не умирай", _once — "только один раз". Комбинируйте их по смыслу.

<<>>

Альтернативный взгляд: автозагрузка и современные практики

В современной PHP-разработке (PHP 7.4+) прямые вызовы require/include для классов почти не используются. Вместо этого применяется автозагрузка через Composer и PSR-4. Но понимание различий всё ещё важно для работы с унаследованным кодом и конфигурационными файлами.

Главный совет: если вы пишете ООП-код, никогда не используйте include или require для классов вручную. Используйте require_once 'vendor/autoload.php' один раз в точке входа, а Composer сам подгрузит нужные файлы. Это решает проблему дублирования и производительности автоматически.

Для конфигурационных файлов есть хитрость: require_once может создать проблему при тестировании, если вы хотите переопределить настройки. В таких случаях используйте require и управляйте потоком выполнения через условия:

<?php
if (!defined('CONFIG_LOADED')) {
    require 'config.php';
    define('CONFIG_LOADED', true);
}
?>

Это даёт гибкость: вы можете принудительно загрузить конфиг заново, сбросив константу. С require_once такой трюк не пройдёт.

Ещё один нюанс: include можно использовать в цикле для динамической подгрузки файлов:

<?php
$files = ['header.php', 'menu.php', 'footer.php'];
foreach ($files as $file) {
    if (file_exists($file)) {
        include $file;
    }
}
?>

Это не сработает с require, так как при отсутствии файла скрипт остановится. Поэтому для гибких решений выбирайте include.

Итог: изучайте автозагрузку Composer, но для ручного управления файлами запомните простое правило — require для обязательного, include для опционального, _once для защиты от дублей.