Перейти к содержимому
Теория · Файлы, пространства имён и Composer · урок 1 из 7

include и require

Чему вы научитесь

Чему вы научитесь:

  • разбивать программу на файлы и подключать их через require и require_once;
  • давать классам полные имена через namespace и сокращать их через use;
  • ставить чужие пакеты через Composer и загружать классы без require;
  • переводить массивы в JSON и обратно через json_encode и json_decode.
Книжная полка, книга greet.php наполовину вынута, над ней закладка require

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

Представьте библиотеку. Каждый файл программы — отдельная книга на свою тему: в одной — функции для приветствий, в другой — настройки сайта.

Когда программе нужна книга, она просит: «возьми с полки вот эту и прочитай прямо сейчас». В PHP такая просьба записывается инструкцией require.

Положим функцию в отдельный файл greet.php:

PHP
<?php

function greet(string $name): string
{
    return 'Hello, ' . $name . '!';
}

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

PHP
<?php

require 'greet.php';

echo greet('Anna'), "\n";
echo greet('Oleg'), "\n";

Запустим главный файл:

TEXT
$ php main.php
Hello, Anna!
Hello, Oleg!

Давайте разберём по шагам:

  1. PHP выполняет main.php сверху вниз и доходит до строки require 'greet.php';.
  2. Он находит greet.php в той же папке и выполняет его целиком: объявляется функция greet.
  3. PHP возвращается в main.php на следующую строку, и функция greet уже известна.
  4. Два вызова greet печатают два приветствия.

Файл выполняется на месте

require выполняет подключённый файл так, будто его текст стоит на месте этой строки. Отсюда три следствия:

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

Путь без папки, как 'greet.php', PHP ищет в папке, откуда запустили скрипт, и в папке файла, где стоит require. Чтобы путь не зависел от того, откуда запустили скрипт, пишут require __DIR__ . '/greet.php';. Константа __DIR__ хранит папку текущего файла.

Файл может вернуть значение

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

PHP
<?php

return [
    'site' => 'Bookshelf',
    'perPage' => 20,
];

Главный файл забирает его в переменную: $config = require 'config.php';. После этого $config['site'] — строка 'Bookshelf', а $config['perPage'] — число 20. Настройки лежат в одном месте, и чтобы их поменять, не нужно искать по всей программе.

Если файла нет

Инструкция include подключает файл так же, как require. Разница одна: что будет, если файла не оказалось на месте.

include: предупреждение

Строка include 'menu.php'; без файла menu.php выдаёт два предупреждения, а скрипт идёт дальше:

TEXT
Warning: include(menu.php): Failed to open stream: No such file or directory
Warning: include(): Failed opening 'menu.php' for inclusion

Страница соберётся, но без меню.

require: Error

Строка require 'footer.php'; без файла выдаёт такое же предупреждение, а потом бросает Error:

TEXT
Warning: require(footer.php): Failed to open stream: No such file or directory
Fatal error: Uncaught Error: Failed opening required 'footer.php'

Как вы уже знаете, непойманный Error останавливает скрипт на этой строке. Поймать его можно через try и catch (Error $e). До PHP 8 здесь была фатальная ошибка, которую не поймать вовсе.

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

Чем include отличается от require — частый вопрос на собеседовании.

require_once

Большая программа подключает одни и те же файлы из разных мест. require_once запоминает, какие файлы уже выполнены, и второй раз тот же файл пропускает. require_once сравнивает полный путь к файлу, поэтому 'greet.php' и __DIR__ . '/greet.php' для него один и тот же файл.

Файл с функциями или классами подключайте через require_once. Обычный require оставьте для файлов вроде config.php, которые возвращают значение: повторный require_once вернул бы вместо массива true.

Частая ошибка

Файл подключили дважды обычным require. Здесь картинка с библиотекой перестаёт работать: книгу можно прочитать два раза, а файл с функцией выполнить дважды нельзя. Пусть mailer.php для своих писем тоже начинается со строки require 'greet.php';:

PHP
<?php

require 'greet.php';
require 'mailer.php'; // ✗

echo greet('Anna'), "\n";
TEXT
Fatal error: Cannot redeclare function greet()

PHP выполняет greet.php второй раз, уже изнутри mailer.php, и пытается снова объявить функцию greet. Объявить функцию дважды нельзя, и скрипт останавливается. Исправление — require_once в обоих файлах: тогда второе подключение пропускается.

Главное

  • require выполняет файл на месте своей строки: его функции, классы и переменные доступны дальше.
  • Файл может вернуть значение через return: так хранят настройки, $config = require 'config.php';.
  • Без файла include выдаёт предупреждение и продолжает, а require бросает Error и останавливает скрипт.
  • require_once выполняет файл один раз — так подключают файлы с функциями и классами.