Menu

PHP include и require: подключение других PHP-файлов

include 'header.php'; выполняет другой PHP-файл в этом месте, будто его код вставлен сюда. require делает то же, но останавливает скрипт фатальной ошибкой, если файла нет, а include лишь предупреждает и продолжает работу. include_once и require_once подключают файл только в первый раз.

На этой странице есть исполняемые редакторы: меняйте, запускайте и сразу видите результат.

include 'header.php'; выполняет код другого PHP-файла в этом месте скрипта, будто он вставлен сюда. require 'header.php'; делает то же самое, но если файл не удаётся загрузить, require останавливает скрипт фатальной ошибкой, а include лишь печатает предупреждение и продолжает работу. Обычно первым делом так подключают шапку и подвал, общие для всех страниц.

Блок сначала записывает header.php и footer.php, чтобы было что подключать. Запустите его и посмотрите на вкладку Page:

Подключаемые файлы это обычные PHP-файлы: в них может быть HTML с тегами <?= ?>, и они видят переменную $title, заданную до require. Измените заголовок и запустите снова; изменение в этом одном файле подхватила бы каждая страница, которая подключает шапку.

include и require

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

Warning: include(sidebar.php): Failed to open stream: No such file or directory in /home/index.php on line 2

Warning: include(): Failed opening 'sidebar.php' for inclusion (include_path='.:/usr/share/php83') in /home/index.php on line 2

require печатает такое же предупреждение и затем выбрасывает Error, который завершает скрипт, если его никто не перехватит:

PHP Warning:  require(config.php): Failed to open stream: No such file or directory in /home/index.php on line 2
PHP Fatal error:  Uncaught Error: Failed opening required 'config.php' (include_path='.:/usr/share/php83') in /home/index.php:2

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

Вывод:

Spring sale: 20% off
banner.php included, include returned int(1)
sidebar.php not found, skipped

include_once и require_once

Файл, который объявляет функцию или класс, можно загрузить только один раз: повторная загрузка это фатальная ошибка, потому что функция уже существует.

Fatal error: Cannot redeclare greet() (previously declared in /home/helpers.php:2) in /home/helpers.php on line 2

Так происходит, как только два файла делают require 'helpers.php'. require_once и include_once запоминают уже загруженные файлы и при повторе их пропускают, возвращая true:

Вывод:

int(1)
bool(true)
bool(true)
Hello, Ada

Используйте формы _once для файлов, которые что-то объявляют, а обычный include для шаблонов, которые нужно вывести больше одного раза. В проектах с Composer файлы классов загружает автозагрузчик, поэтому вызовы require_once для классов в основном исчезают; смотрите Composer.

Возврат значения из подключённого файла

return на верхнем уровне подключённого файла останавливает этот файл и передаёт значение обратно выражению include или require. Так получается аккуратный файл настроек: никаких глобальных переменных, только значение, которое вы присваиваете переменной с любым именем.

Вывод:

My Shop
shop
bool(false)

Так устроены файлы настроек Laravel (config/app.php, config/database.php и остальные).

Переменные и область видимости в подключённых файлах

Подключённый код выполняется в области видимости той строки, которая его подключает. В начале скрипта он видит все глобальные переменные; внутри функции только локальные переменные этой функции. На втором правиле построен крошечный шаблонизатор: функция, локальные переменные которой это ровно те переменные, которые должен видеть шаблон.

Вкладка Page показывает оба списка, отрисованные из одного файла шаблона. Поскольку include выполняется внутри render(), шаблон видит $heading и $products, но не $secret. Форма foreach ... endforeach, используемая в шаблоне, это альтернативный синтаксис, который PHP предлагает для HTML-шаблонов.

Пути подключения и DIR

Путь вроде 'helper.php' разрешается не относительно файла, который содержит include. PHP ищет в настройке include_path (которая обычно начинается с ., текущего рабочего каталога) и только потом в папке самого подключающего файла. Поэтому внутри partials/nav.php include 'helper.php' может загрузить совсем другой helper.php из корня проекта. __DIR__, каталог текущего файла, убирает гадание:

Вывод:

loaded the root helper.php
loaded partials/helper.php
__DIR__ in nav.php is partials

Пишите каждое подключение как __DIR__ . '/relative/path.php'. Рабочий каталог зависит от того, как запущен скрипт (веб-сервер, задача cron, командная строка из другой папки), а __DIR__ не меняется никогда.

Никогда не подключайте файл, имя которого задал пользователь

Частый первый маршрутизатор читает имя страницы из URL: include $_GET['page'] . '.php';. Это позволяет посетителю выбрать, какой файл на сервере выполнится, например ?page=../../config (включение локального файла), а при старых настройках даже файл с другого сервера. Вместо этого сопоставьте разрешённые имена с файлами. Запустите блок и нажимайте на ссылки: каждое нажатие снова запускает скрипт с другим $_GET['page'].

До require могут дойти только три имени из $pages; ссылка ../secret получает страницу "Not found". Безопасное чтение значений запроса описано в GETи_GET и _POST.

Часто задаваемые вопросы

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

Оба загружают и выполняют другой PHP-файл. Если файл не удаётся загрузить, require останавливает скрипт фатальной ошибкой, а include печатает предупреждение, возвращает false и даёт скрипту продолжить работу. Используйте require для файлов, без которых страница не может работать, например файлов настроек и библиотек функций.

Когда использовать require_once вместо require?

Используйте require_once для файлов, которые объявляют функции, классы или константы. Повторная загрузка такого файла это фатальная ошибка (Cannot redeclare), а require_once пропускает файл, если он уже загружен. Шаблоны, которые вы хотите вывести несколько раз, подключают обычным include.

Может ли подключённый PHP-файл вернуть значение?

Да. return на верхнем уровне подключённого файла завершает его и становится значением выражения include или require: $config = require 'config.php'; с return ['debug' => true]; в config.php. Без return include равен 1.

Видит ли подключённый файл мои переменные?

Да. Подключённый код выполняется в области видимости той строки, которая его подключает: в начале скрипта он видит глобальные переменные, а внутри функции видит локальные переменные этой функции и больше ничего. Создаваемые им переменные попадают в ту же область видимости.

Как писать: include('file.php') или include 'file.php'?

Работает и так, и так, потому что include и require это языковые конструкции, а не функции; скобки лишь оборачивают путь. Большинство стандартов оформления пишут require 'file.php'; без них.

Иллюстрация языков программирования Coddy

Учитесь программировать с Coddy

НАЧАТЬ