Чат 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';
Онлайн обучение PHP
Путь с полного нуля до джуниора!
Начать бесплатно
Читайте также
Курс программирования на PHP
Подготовка до уровня устройства на работу!
Начать бесплатно
Комментарии (41)


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

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

bratko

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

$content = '<h1>Заголовок статьи</h1><p>Текст какой-то статьи</p>';

Потому как глядя на тебя, я тоже стал использовать теги в переменных.

ivashkevich

Сорри, всё правильно)

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-код, не ставится. Можете погуглить почему. И спасибо что помогли ученику выше :)

bratko

По поводу задания:

$var = include 'file.php';

Интересно, правильный ли мой вариант..
В index.php я добавил код:

$var = include __DIR__ . '/file.php';

В file.php я добавил:

<?php
$social = 'Социальные кнопки для FOOTER';
return $social;
?>

И теперь в footer.php вставил в специальном нужном мне месте:

<?= $var ?>

И всё работает. Получается из footer.php идет обращение к переменной $var, которая находится в index.php и в которую был положен file.php, а в file.php уже то что мне нужно, чтоб вывелось в footer.php в нужном месте. Но возник сразу вопрос, правильно ли это? Потому как в file.php могут быть разные переменные и разные данные и тогда в нужном мне месте выведет кучу информации, которая не актуальна для того места. Как тогда быть?

ivashkevich

Всё правильно. А для того чтобы были только нужные переменные в нужном месте, стоит подключать файлы там, где они непосредственно нужны (в твоем примере подключать file.php внутри footer.php)

Starosta
<?php

$nameHeader='Warhhamer 40000';
$advertising='Валидол';
$warhImper='Император';
$creatorSite='Starosta';

require __DIR__ . '/header.php';
require __DIR__ . '/siderbar.php';
require __DIR__ . '/content.php';
require __DIR__ . '/footer.php';

файл header. В остальных так же выводятся переменные.

<!DOCTYPE html>

<html>
<head>
    <title>Warhammer 40000</title>
    <style>
        table, td {
            border: solid black 1px;
            border-collapse: collapse;
        }

        #layout {
            width: 800px;
            margin: auto;
        }

        #layout td {
            padding: 20px;
        }

        #sidebar {
            width: 300px
        }
    </style>
</head>
<body>
<table id="layout">
    <tr>
        <td colspan="2"><center><?php echo $nameHeader; ?></center></td>
    </tr>
ivashkevich

А тайтл почему захардкожен?

Starosta

Не совсем понял что значит захардкожен? Из двух слов?

ivashkevich

Почему текст между тегами title явно написан. Должна использоваться переменная $nameHeader по идее

Pro100Bah

Сделал по уроку

<?php

$content = '<h1>Заголовок статьи</h1><p>Текст какой-то статьи</p>';
$header = '<h1>Что-то вношу в заголовок...</h1><br><p>Вроде понимаю как это все делать)))</p>';
$header1 = '<h2><img src="/images/prog.jpg" width="200" alt="Картинка программиста"></h2><p>Красота!!!</p>';
$header2 = '<p><strong>Нелегкий труд учить PHP</strong></p>';
$header3 = '<h4><a href="https://webshake.ru">Ссылка на курс, который я учу!!!</a> </h4><br><p>Тяжело</p>';
require __DIR__ . '/header.php';
require __DIR__ . '/sidebar.php';
require __DIR__ . '/content.php';
require __DIR__ . '/footer.php';

А вот код куда вставлены переменные

<html>
<head>
    <title>Заголовок страницы</title>
    <style>
        table, td {
            border: solid #000000 1px;
            border-collapse: collapse;
        }

        #layout {
            width: 800px;
            margin: auto;
        }

        #layout td {
            padding: 20px;
        }

        #sidebar {
            width: 300px
        }
    </style>
</head>
<body>
<table id="layout">
    <tr>
        <td colspan="2"><?= $header, $header1, $header2, $header3?></td>
    </tr>
    <tr>

Не стал делать для каждого блока сделал для одного . Думаю правильно понял задание.

ivashkevich

Вполне норм, только конкатенацию строк нужно делать через точку, а не через запятую.

Самый понятный курс PHP
Онлайн-уроки в удобное время!
Начать бесплатно
Популярное за сутки
Онлайн-курсы PHP и MySQL
Обучение с полного нуля до уровня джуниора!
Начать бесплатно
Сейчас читают
Онлайн-курсы PHP и MySQL
Обучение с полного нуля до уровня джуниора!
Начать бесплатно
Новые статьи
Логические задачи с собеседований