Чат PHP-разработчиков
Подключение файлов в PHP: include и require

Подключение файлов в PHP

В PHP имеется возможность подключать файлы с кодом внутри других файлов. Это делается для того, чтобы выстроить архитектуру приложения.

Архитектура программного обеспечения (англ. software architecture) — совокупность важнейших решений об организации программной системы. Архитектура включает:

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

То есть нам нужно разбивать наш код на отдельные части, каждая из которых будет выполнять свою роль. К примеру, можно вынести какие-то функции в отдельный файл, подключить этот файл внутри другого, и пользоваться ими уже в этом файле.

Смысл архитектуры в том, чтобы компоненты программы, отвечающие за какое-то похожее поведение, лежали в одном месте, и их можно было легко найти и изменить.

Ну а вообще, давайте на примере. Но сначала давайте изучим одну «магическую» константу. Речь идёт о константе __DIR__. В ней содержится путь до директории, в которой находится текущий скрипт (скрипт, в котором эта константа была использована).

Давайте запишем в наш index.php следующий код:

Код доступен только после покупки курса PHP для начинающих.

Результат этого кода:

Код доступен только после покупки курса PHP для начинающих.

Вуаля, мы теперь знаем, в какой папке находится index.php. Мы будем всегда использовать магическую константу __DIR__ при указании путей подключаемых файлов. При этом в выражениях для подключения файлов следует избегать данных от пользователей, чтобы избежать хакерских атак под названием PHP-injections. Подробнее читайте здесь.

Ну а теперь вернёмся к основной теме урока. Создадим в директории с index.php ещё один файл с именем functions.php и заполним его следующим содержимым:

Код доступен только после покупки курса PHP для начинающих.

Теперь вернёмся в index.php и запишем в него следующий код:

Код доступен только после покупки курса PHP для начинающих.

Надеюсь, никто не забыл, что можно вставлять PHP-код прямо внутри HTML? Об этом мы говорили в этом уроке. Только там мы использовали для вывода конструкцию вида:

Код доступен только после покупки курса PHP для начинающих.

Если во вставке нам нужно только вывести результат какого-то выражения, то её можно упростить до:

Код доступен только после покупки курса PHP для начинающих.

И если сейчас мы зайдём в браузере на URL нашего приложения, то увидим следующее:
Работа директивы include

Наше приложение успешно отработало, и основной код страницы у нас не содержит вспомогательных функций – они с помощью директивы include подключились в наш файл. Если говорить более детально – PHP-код из файла functions.php был вставлен в то место, где он был подключен с помощью директивы include.

Разница между require и include

Есть ещё одна директива для подключения файлов – require. Если вы сейчас замените include на require, вот так:

Код доступен только после покупки курса PHP для начинающих.

то ничего по сути не изменится – код отработает точно так же.

Однако между ними всё же есть разница. Она заключается в том, что если подключаемый файл не найден, то при include возникнет warning, но программа продолжит своё выполнение. А если подключаемого не окажется при попытке выполнить require, то произойдёт фатальная ошибка и скрипт завершит свою работу.

Давайте снова вернём директиву include, переименуем functions.php в abc.php и попробуем обновить страничку.

Ошибка подключения с типом warning

Получили ошибки разных типов. Первая из них – warning, сообщающий о том, что файл functions.php не найден. Но скрипт продолжил своё выполнение, а затем упал на строке 10 из-за того, что не была найдена функция isEven(), а это уже fatal error.
Давайте теперь заменим include на require и снова обновим страничку.
Фатальная ошибка при отсутствии файла

Теперь мы получили fatal error сразу на второй строке, приложение завершило свою работу на этом месте.

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

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

Как ещё можно использовать require и include

Помимо того, что можно подключать файлы с PHP-кодом, можно также подключать файлы, содержащие какой-то текст, или в частности HTML-код.

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

Зелёным цветом я выделил ту часть странички, которая будет изменяться.

Давайте для начала сверстаем наш шаблон. Надеюсь, все прошли курс по HTML. У меня получился вот такой код:

Код доступен только после покупки курса PHP для начинающих.

Вот такая получилась у меня веб-страничка:
Свёрстанная страничка

Давайте теперь разобьём этот код на компоненты. Создадим 4 файла: header.php с шапкой файла, sidebar.php с боковой колонкой, content.php с основным содержимым страницы и footer.php для подвала сайта.

header.php:

Код доступен только после покупки курса PHP для начинающих.

sidebar.php:

Код доступен только после покупки курса PHP для начинающих.

content.php:

Код доступен только после покупки курса PHP для начинающих.

footer.php:

Код доступен только после покупки курса PHP для начинающих.

А теперь вернёмся в index.php и запишем в него следующий код:

Код доступен только после покупки курса PHP для начинающих.

Обновим страничку и увидим, что она по-прежнему работает. Только теперь она собралась из маленьких кусочков, каждый из которых отвечает за свою часть.

В подключаемых файлах мы можем использовать переменные, которые были определены до их подключения. К примеру, давайте в index.php добавим переменную $content:

Код доступен только после покупки курса PHP для начинающих.

А в файле content.php выведем эту переменную:

Код доступен только после покупки курса PHP для начинающих.

Давайте теперь снова обновим страничку:
Динамически сформированная страничка

Та-да! Наша страничка сформировалась динамически! Мало того, что она была собрана из разных компонентов, так она ещё и выводит значения из переменных.

Директивы require_once и include_once

Иногда нужно, чтобы файл подключился только один раз. Например, чтобы только однажды подключить файл с функциями. Для этого используются директивы require_once и include_once.

Давайте создадим файл config.php и запишем в него следующее содержимое:

Код доступен только после покупки курса PHP для начинающих.

И теперь создадим файл test.php и напишем следующий код:

Код доступен только после покупки курса PHP для начинающих.

Теперь давайте запустим test.php, перейдя по адресу в браузере: http://myproject.loc/test.php

И увидим, что текст вывелся только однажды.
Только одно подключение файла

Теперь давайте заменим include_once на include:

Код доступен только после покупки курса PHP для начинающих.

А вот теперь код подключился несколько раз:
Несколько подключений

Вот такие пирожки. Чуть позже мы ещё вернёмся к теме этих отличий, и когда именно стоит использовать include_once и require_once.

А пока что на этом всё. Делайте домашнее задание и до встречи на следующих уроках!

Домашнее задание
  • Самостоятельно создайте архитектуру, описанную в статье: сделайте шапку, сайдбар, контент и футер в отдельных файлах.
  • Сделайте минимум 4 переменные для каждого из этих блоков в файле index.php и выведете их внутри этих файлов.
  • Изучите официальную документацию по include и изучите как можно использовать выражения вида
    $var = include 'file.php';
Читайте также
Комментарии (30)


SBTesla

Когда следующий урок?)

ivashkevich

В эти выходные запилю, обещаю)

serb2017

В задании:

$var = include 'file.php';

Необычный результат получается.

var_dump($var);

Показывает int(1) 1

echo $var;

На экран вывел целую таблицу (header.php как в примерах выше)

ivashkevich

Ну что же вы не осилили документацию?) В задании же написано что сначала нужно изучить.
P.S. Если уж совсем лень, то смотрите пункт "Выражения include и return". На момент написания данного комментария это "Пример #5".

Max

У вас на редкость хорошие уроки, среди мегатонн разной хрени по интернету. Сужу по тому, что рекомендуете всегда пользоваться DIR при подключении. Многим это неведомо.

1nSide

Типа такого должно получится?
index.php

<?php

$content = file_get_contents(__DIR__ . '/news1.txt');

require __DIR__ . '/header.php';
include __DIR__ . '/sidebar.php';
//require __DIR__ . '/sidebar.php';
require __DIR__ . '/content.php';
require __DIR__ . '/footer.php';

sitedar.php

   <td id="sidebar">
        <?=
        $sidebar = 'Меню сайта';

            return $sidebar;
        ?>
    </td>
ivashkevich

Типа того, только закомментированные строчки кода ни к чему.

1nSide
<?php

$content = file_get_contents(__DIR__ . '/news1.txt');

require __DIR__ . '/header.php';
$sidebar = include 'sidebar.php';
//include __DIR__ . '/sidebar.php';
//require __DIR__ . '/sidebar.php';
require __DIR__ . '/content.php';
require __DIR__ . '/footer.php';
1nSide

Или так?

ivashkevich

Нет, первый вариант правильный. Использование результата include или return нужно в случае, когда подключаемый файл возвращает что-либо через return. Иначе - результатом подключения файла будет 1.

$x = include __DIR__ . '1.php'; // $x == 1

Если же в файле 1.php будет что-то типа:

return 2 + 3;

То в таком случае в $x попадёт 5.

Для подключения шаблонов внутри других шаблонов можно просто писать

include __DIR__ . '/sidebar.php';
ppixx@mail.ru

Отличные уроки - лучшее что удалось найти в сети

ivashkevich

Спасибо :)

RomVR

А константа DIR присутствует только в OpenServer? Я Ваши примеры и задания выполняю в Ubuntu 16.04 (Apache2, PHP7.0) и DIR никак не проходит.

RomVR

Всё нашёл в официальной документации по PHP. Извиняюсь за беспокойство. :)

ivashkevich

Хорошо, привыкайте читать документацию ;)

vityan97@gmail.com

Такой вопрос.
Вижу тут нужно было до этого пройти курс по хтмл, я его не проходил ещё, вернее несколько месяцев назад хотел пройти, но забросил, знаю кое-что. Стоит ли его сейчас пройти? Либо это всё можна подхватить по ходу дела, просто уже начал php, чувствую что если начну html, то когда вернусь к php снова, многое из курса выпадет из головы. Посоветуйте как быть.

ivashkevich

Если основы HTML хоть чуть-чуть изучали, то можете продолжать.

stasokulov@gmail.com
<?php

$header = "<h1>Сайт, который я учусь делать с помощью ПХП</h1>";
$header1 = "Красивый слоган";
$sidebar = "Пункт 1<br>Пункт 2<br>Пункт 3<br>Пункт 4<br>";
$content = '<h2>Заголовок статьи</h2><p>Текст какой-то статьи</p>';
$footer = "Здесь, допустим, будут контакты.";

require __DIR__ . '/header.php';
require __DIR__ . '/sidebar.php';
require __DIR__ . '/content.php';
require __DIR__ . '/footer.php';
stasokulov@gmail.com

На 4 переменные для каждого блока фантазии не хватило)

Mike
<?php
$header = '<h1> название сайта</h1><p>Сайт о том что...</p>';
$sidebar= '<h2> Меню </h2> <br><ol>Список<li>One</li><li>Two</li><li>Three</li></ol>';
$content= '<h2> Основной контент</h2> <br> <p>Случайное число <b>' . random_int(0,99) .'</b></p>';
$footer = 'Все права защищены (c) 2018г ';
require __DIR__ . '/header.php';
require __DIR__ . '/sidebar.php';
require __DIR__ . '/content.php';
require __DIR__ . '/footer.php';
ivashkevich

В переменных теги не нужны - их нужно хранить в шаблоне.

7vs13@inbox.ru

А почему вот эта строчка:
$varInc = require 'footer.php';
Является аналогом вот этой:
require './footer.php';
?
Не знаю, правда, можно ли это коротко объяснить будет)

virtual2018

так как во всех операционных системах общее правило для каталогов (папок):
../ - это обращение к каталогу один уровень вверх
./ - это обращение к каталогу в котором находимся.
По умолчанию считается, что если перед именем файла ничего не указано, например footer.php, то это равнозначно ./footer.php

7vs13@inbox.ru

Это я понимаю. Вопрос немного не в этом был. Когда я пишу в коде вот эту строчку:
$varInc = require 'footer.php';
То у меня подключается файл footer.php
Точно также, как он подключается, когда я пишу вот это:
require './footer.php';
То есть в первом случае я как бы просто инициализирую переменную $varInc и больше ничего не делаю, но при этом у меня происходит подключение файла, как-то это нелогично. То есть обе эти строки по отдельности делают одно и тоже. Может у меня что не так работает_))

virtual2018

require 'footer.php' - помимо собственно подключения файла footer.php, всегда возвращается еще и результат этого действия, просто в первом случае Вы его используете передавая в переменную и потом сравнив можете что-то еще сделать: повесить функцию, выдать сообщение и т.п., а во втором случае просто не используете.

7vs13@inbox.ru

Ага, вроде понял, спасибо

virtual2018

//index.php

<?php
?>
<html>
<head>
    <title>Особенности использования include</title>
</head>
<body>
<? $str = include __DIR__.'/string.php'; echo $str; ?>
<!--выведем строку так как в string.php есть return  -->
<br>
<? $str = include __DIR__.'/no_string.php'; echo $str; echo '<br>'.$stringText ?>
<!-- сначала выведем 1, файл no_string.php успешно подключен, а потом переменную 
stringText -->
<br>
</body>
</html>

//string.php

<?php
    $stringText = '<h2> Test return string </h2>';
    return $stringText;
?>

//no_string.php

<?php
    $stringText = '<h2> Test return string </h2>';
?>
ivashkevich

В index.php теги PHP в начале файла ни к чему. Закрывающий тег в файлах, в которых только PHP-код, не ставится. Можете погуглить почему. И спасибо что помогли ученику выше :)

Популярное за сутки
Сейчас читают
Логические задачи с собеседований