Подключение файлов в PHP
В PHP имеется возможность подключать файлы с кодом внутри других файлов. Это делается для того, чтобы выстроить архитектуру приложения.
Архитектура программного обеспечения (англ. software architecture) — совокупность важнейших решений об организации программной системы. Архитектура включает:
– выбор структурных элементов и их интерфейсов, с помощью которых составлена система, а также их поведения в рамках сотрудничества структурных элементов;
– соединение выбранных элементов структуры и поведения во всё более крупные системы;
– архитектурный стиль, который направляет всю организацию — все элементы, их интерфейсы, их сотрудничество и их соединение.
То есть нам нужно разбивать наш код на отдельные части, каждая из которых будет выполнять свою роль. К примеру, можно вынести какие-то функции в отдельный файл, подключить этот файл внутри другого, и пользоваться ими уже в этом файле.
Смысл архитектуры в том, чтобы компоненты программы, отвечающие за какое-то похожее поведение, лежали в одном месте, и их можно было легко найти и изменить.
Ну а вообще, давайте на примере. Но сначала давайте изучим одну «магическую» константу. Речь идёт о константе __DIR__. В ней содержится путь до директории, в которой находится текущий скрипт (скрипт, в котором эта константа была использована).
Давайте запишем в наш index.php следующий код:
<?php
echo __DIR__;
Результат этого кода:
C:\OpenServer\domains\myproject.loc\www
Вуаля, мы теперь знаем, в какой папке находится index.php. Мы будем всегда использовать магическую константу __DIR__ при указании путей подключаемых файлов. При этом в выражениях для подключения файлов следует избегать данных от пользователей, чтобы избежать хакерских атак под названием PHP-injections. Подробнее читайте здесь.
Ну а теперь вернёмся к основной теме урока. Создадим в директории с index.php ещё один файл с именем functions.php и заполним его следующим содержимым:
<?php
function isEven(int $x)
{
return $x % 2 === 0;
}
Теперь вернёмся в index.php и запишем в него следующий код:
<?php
include __DIR__ . '/functions.php';
?>
<html>
<head>
<title>Чётные и нечётные числа</title>
</head>
<body>
Число 2 <?= isEven(2) ? 'чётное' : 'нечётное' ?>
<br>
Число 5 <?= isEven(5) ? 'чётное' : 'нечётное' ?>
<br>
Число 8 <?= isEven(8) ? 'чётное' : 'нечётное' ?>
</body>
</html>
Надеюсь, никто не забыл, что можно вставлять PHP-код прямо внутри HTML? Об этом мы говорили в этом уроке. Только там мы использовали для вывода конструкцию вида:
<?php echo 2 + 2; ?>
Если во вставке нам нужно только вывести результат какого-то выражения, то её можно упростить до:
<?= 2 + 2; ?>
И если сейчас мы зайдём в браузере на URL нашего приложения, то увидим следующее:
Наше приложение успешно отработало, и основной код страницы у нас не содержит вспомогательных функций – они с помощью директивы include подключились в наш файл. Если говорить более детально – PHP-код из файла functions.php был вставлен в то место, где он был подключен с помощью директивы include.
Разница между require и include
Есть ещё одна директива для подключения файлов – require. Если вы сейчас замените include на require, вот так:
require __DIR__ . '/functions.php';
то ничего по сути не изменится – код отработает точно так же.
Однако между ними всё же есть разница. Она заключается в том, что если подключаемый файл не найден, то при include возникнет warning, но программа продолжит своё выполнение. А если подключаемого не окажется при попытке выполнить require, то произойдёт фатальная ошибка и скрипт завершит свою работу.
Давайте снова вернём директиву include, переименуем functions.php в abc.php и попробуем обновить страничку.
Получили ошибки разных типов. Первая из них – warning, сообщающий о том, что файл functions.php не найден. Но скрипт продолжил своё выполнение, а затем упал на строке 10 из-за того, что не была найдена функция isEven(), а это уже fatal error.
Давайте теперь заменим include на require и снова обновим страничку.
Теперь мы получили fatal error сразу на второй строке, приложение завершило свою работу на этом месте.
То есть require нужно использовать там, где подключение файла обязательно. Например, файл с конфигурацией, или необходимыми функциями.
А include можно использовать для файлов, которые необязательно должны быть подключены (если без них можно продолжать выполнение кода). Пример: файл с кодом баннерной рекламы. Да, реклама не покажется, но зато сайт продолжит свою работу.
Как ещё можно использовать require и include
Помимо того, что можно подключать файлы с PHP-кодом, можно также подключать файлы, содержащие какой-то текст, или в частности HTML-код.
Предлагаю рассмотреть следующую ситуацию: у нас на сайте всегда одинаковая шапка, боковая панель, и футер, но при этом меняются заголовок и содержимое страницы. Предположим, наш сайт выглядит так:
Зелёным цветом я выделил ту часть странички, которая будет изменяться.
Давайте для начала сверстаем наш шаблон. Надеюсь, все прошли курс по HTML. У меня получился вот такой код:
<html>
<head>
<title>Заголовок страницы</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">HEADER</td>
</tr>
<tr>
<td id="sidebar">SIDEBAR</td>
<td>CONTENT</td>
</tr>
<tr>
<td colspan="2">FOOTER</td>
</tr>
</table>
</body>
</html>
Вот такая получилась у меня веб-страничка:
Давайте теперь разобьём этот код на компоненты. Создадим 4 файла: header.php с шапкой файла, sidebar.php с боковой колонкой, content.php с основным содержимым страницы и footer.php для подвала сайта.
header.php:
<html>
<head>
<title>Заголовок страницы</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">HEADER</td>
</tr>
<tr>
sidebar.php:
<td id="sidebar">SIDEBAR</td>
content.php:
<td>CONTENT</td>
footer.php:
</tr>
<tr>
<td colspan="2">FOOTER</td>
</tr>
</table>
</body>
</html>
А теперь вернёмся в index.php и запишем в него следующий код:
<?php
require __DIR__ . '/header.php';
require __DIR__ . '/sidebar.php';
require __DIR__ . '/content.php';
require __DIR__ . '/footer.php';
Обновим страничку и увидим, что она по-прежнему работает. Только теперь она собралась из маленьких кусочков, каждый из которых отвечает за свою часть.
В подключаемых файлах мы можем использовать переменные, которые были определены до их подключения. К примеру, давайте в index.php добавим переменную $content:
<?php
$content = '<h1>Заголовок статьи</h1><p>Текст какой-то статьи</p>';
require __DIR__ . '/header.php';
require __DIR__ . '/sidebar.php';
require __DIR__ . '/content.php';
require __DIR__ . '/footer.php';
А в файле content.php выведем эту переменную:
<td><?= $content ?></td>
Давайте теперь снова обновим страничку:
Та-да! Наша страничка сформировалась динамически! Мало того, что она была собрана из разных компонентов, так она ещё и выводит значения из переменных.
Директивы require_once и include_once
Иногда нужно, чтобы файл подключился только один раз. Например, чтобы только однажды подключить файл с функциями. Для этого используются директивы require_once и include_once.
Давайте создадим файл config.php и запишем в него следующее содержимое:
<?php
echo 'Это просто заглушка вместо конфига.';
И теперь создадим файл test.php и напишем следующий код:
<?php
include_once __DIR__ . '/config.php';
include_once __DIR__ . '/config.php';
include_once __DIR__ . '/config.php';
Теперь давайте запустим test.php, перейдя по адресу в браузере: http://myproject.loc/test.php
И увидим, что текст вывелся только однажды.
Теперь давайте заменим include_once на include:
<?php
include __DIR__ . '/config.php';
include __DIR__ . '/config.php';
include __DIR__ . '/config.php';
А вот теперь код подключился несколько раз:
Вот такие пирожки. Чуть позже мы ещё вернёмся к теме этих отличий, и когда именно стоит использовать include_once и require_once.
А пока что на этом всё. Делайте домашнее задание и до встречи на следующих уроках!
Комментарии