Avatar ·

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

Всем привет! Я только начал изучать PHP и никак не могу понять разницу между этими четырьмя конструкциями для подключения файлов. Вроде бы все делают одно и то же — вставляют код из другого файла.

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

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

И я подключаю его в index.php разными способами:

<?php
include 'config.php';
// или
require 'config.php';
// или
include_once 'config.php';
// или
require_once 'config.php';
?>

Все четыре варианта работают, и я вижу переменные из config.php. В чем тогда разница? Когда что использовать?

Еще я заметил странную вещь: если я дважды напишу include 'config.php', то получаю ошибку, что переменные переопределяются. А с include_once такой проблемы нет. Почему так происходит?

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

Объясните, пожалуйста, на простых примерах, когда какую конструкцию применять. Желательно с реальными сценариями из жизни.

<<>>

Подробное сравнение include, require, include_once и require_once

Давайте разберем каждую конструкцию на конкретных примерах. Главное отличие — это поведение при ошибке и контроль повторного подключения.

1. include — "попробуй подключить, но не умирай"

include подключает файл и выполняет его код. Если файл не найден, PHP выдаст предупреждение (warning), но скрипт продолжит работу.

<?php
include 'несуществующий_файл.php'; // Warning: include(): Failed opening...
echo "Скрипт продолжает работу!"; // Это выполнится
?>

Когда использовать: для необязательных компонентов (виджеты, шаблоны, рекламные блоки). Если файл пропал — сайт просто не покажет эту часть, но не сломается.

2. require — "подключи или умри"

require делает то же самое, но при отсутствии файла выбрасывает фатальную ошибку (fatal error) и останавливает выполнение скрипта.

<?php
require 'несуществующий_файл.php'; // Fatal error: require(): Failed opening...
echo "Этот код НЕ выполнится";
?>

Когда использовать: для критически важных файлов (конфигурация БД, классы ядра, маршрутизатор). Без них работа приложения невозможна.

3. _once — защита от повторного подключения

Суффикс _once проверяет, был ли уже подключен данный файл. Если да — повторное подключение игнорируется. Это спасает от:

  • Переопределения функций/классов (фатальная ошибка)
  • Дублирования переменных
  • Бесконечных циклов подключения
<?php
// Файл functions.php
function hello() { echo "Привет!"; }

// Основной файл
require_once 'functions.php';
require_once 'functions.php'; // Второй раз игнорируется
hello(); // Работает без ошибок
?>

А если бы мы использовали require дважды:

<?php
require 'functions.php';
require 'functions.php'; // Fatal error: Cannot redeclare hello()
?>

Сводная таблица

Конструкция Поведение при ошибке Защита от дублей Пример использования
include Warning, скрипт жив Нет Подключение шаблона футера
require Fatal error, скрипт мертв Нет Подключение файла с настройками БД
include_once Warning, скрипт жив Да Подключение виджета, который может быть вызван повторно
require_once Fatal error, скрипт мертв Да Подключение классов, функций, автозагрузка

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

  1. Для конфигурации и базовых классов всегда используйте require_once — это стандарт в современных фреймворках.
  2. Для шаблонов (header, footer) используйте include — они не критичны.
  3. Для библиотек функций используйте require_once, чтобы избежать конфликтов имен.
  4. Избегайте include для файлов с объявлениями классов/функций — при повторном вызове получите фатальную ошибку.

В вашем примере с config.php лучше всего подойдет require_once, так как:

  • Без настроек БД сайт не будет работать — нужен require
  • Защита от случайного двойного подключения — нужен _once
<<>>

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

Хотя базовое понимание include/require важно, в современной PHP-разработке (PHP 7+) на практике эти конструкции используются реже. На смену пришли автозагрузка классов и менеджеры зависимостей (Composer).

Основные минусы ручного подключения файлов:

  • Производительность: при каждом include/require PHP тратит время на поиск, открытие и компиляцию файла. При 50+ подключениях это заметно.
  • Сложность поддержки: легко запутаться в цепочке зависимостей и забыть подключить нужный файл.
  • Конфликты имен: если два файла объявляют функцию с одинаковым именем — получите ошибку.

Современный подход — использовать автозагрузку через Composer:

// composer.json
{
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    }
}

После composer dump-autoload вам достаточно подключить один файл:

<?php
require_once __DIR__ . '/vendor/autoload.php';

use App\Core\Router;
$router = new Router(); // Класс подгрузится автоматически
?>

Это полностью решает проблему выбора между include/require. Если вы пишете на чистом PHP без фреймворков — используйте require_once для критичных файлов и include для шаблонов. Но если проект растет — сразу переходите на автозагрузку.

Еще один совет: никогда не используйте include_once для файлов с функциями — это медленнее, чем require_once, из-за дополнительной проверки. Для функций всегда require_once.