Разница между require, include, require_once и include_once?
Содержание:
PHP include and require Statements
It is possible to insert the content of one PHP file into another PHP file (before the
server executes it), with the include or require statement.
The include and require statements are identical, except upon failure:
- will produce a fatal error (E_COMPILE_ERROR) and stop the script
- will only produce a warning (E_WARNING) and the script will continue
So, if you want the execution to go on and show users the output, even if the
include file is missing, use the include statement. Otherwise, in case of FrameWork, CMS, or a
complex PHP application coding, always use the require statement to include a key file to the
flow of execution. This will help avoid compromising your application’s security
and integrity, just in-case one key file is accidentally missing.
Including files saves a lot of work. This means that
you can create a standard header, footer, or menu file for all your web pages.
Then, when the header needs to be updated, you can only
update the header include file.
Предисловие
Не так давно проект, на котором я работаю в данный момент, начал использовать модульную систему ES2015
Я не буду заострять внимание на этой технологии JavaScript, т.к статья совсем не об этом, а о том как технология сподвигла меня к одной мысли
Как многие знают, ES2015 Modules представляют собой импортирование/экспортирование скриптов крайне схожее по синтаксису с и многими другими языками программирования. Пример:
Все, кто интересовался модулями JavaScript знают, что импортирование и экспортирование возможно только на верхнем уровне модуля (файла с кодом).
Следующий грубый пример кода вызовет ошибки:
В отличие от ES2015 Modules — в модульной системе импортирование и экспортирование возможны на любом уровне вложенности.
Аналогичный код на не вызовет ошибку:
Преимущество такого способа в том, что модули необходимые в обработчике явно импортированы внутри и не засоряют пространство имен модуля (особенно актуально, если импортируемый модуль нужен только в одном обработчике). Так же появляется возможность отложенного экспортирования данных модуля.
Основные минусы:
- Об отсутствии модуля вы узнаете только во время вызова соответствующего обработчика
- Путь к импортироемому модулю может измениться, что приведет к изменению в каждом месте импортирования (например, в вашем модуле, в различных обработчиках используется и вы решили до 4.x версии, где подключать нужно ).
Способы подключения файлов
Для подключения файлов в PHP есть две языковых конструкции: и . Чем же они отличаются? На самом деле, отличия между ними минимальны. Оба этих ключевых слова подключают файл с указанным именем и вызывают ошибку, если данный файл не существует.
Однако особенность работы состоит в том, что файл будет подключен только один раз, даже если вызвать эту инструкцию несколько раз с одним именем файла.
Примеры подключения файлов
Для начала посмотрим, как просто подключить один сценарий внутри другого. Для этого воспользуемся инструкцией . Предположим, у нас есть два сценария: и .
Содержимое файла :
В файле находится код, который подключит сценарий :
Интересный факт: можно использовать как ключевое слово, либо как функцию.
Результат будет одним и тем же:
Результат работы:
Привет, я содержимое из sub.php! А я - index.php!
Что произошло? Два сценария как бы склеились в один: выполнилось все содержимое и добавилось в начало сценария .
О том, как работать с функцией , подробно рассказано в этом задании.
Разбор полетов
В большинстве задач для которых используется — front-end или основной веб-сервер, и высокая нагрузка на частое явление. Пропуская способность вашего сервера должны быть максимально возможная.
Измерение пропускной способности
Для измерения пропускной способности веб-сервера используется великолепная утилита от Apache — ab. Если вы еще с ней не знакомы, то настоятельно рекомендую это сделать.
Код веб-сервера одинаков за исключением обработчиков.
Тест запускался на с использованием модуля , сделанного на базе
Код:
Результат:
Код:
Результат:
Анализ результатов
Импортирование модулей в начале файла уменьшило время одного запроса на ~23%(!) (в сравнение с импортированием непосредственно в обработчик), что весьма существенно.
Такая большая разница в результатах кроется в работе функции . Перед импортированием, обращается к алгоритму поиска абсолютного пути к запрашиваемому компоненту (алгоритм в документации node.js). Когда путь был найден, то проверяет был ли закеширован модуль, и если нет — не делает ничего сверхестественного, кроме для и форматов, и для загрузки C++ модулей.
Note: пробовал «прогревать» кеш для случая с непосредственным импортированием модулей в обработчик (перед запуском утилиты ab, модули были уже закешированы) — производительность улучшалась на 1-2%.
Выводы
Если вы используете node.js, как сервер (нет разницы какой — TCP/UDP или HTTP(S)), то:
- Импортирование всех модулей необходимо делать в начале файла, чтобы избегать лишних синхронных операций связанных с загрузкой модулей (один из главных анти-паттернов использования node.js как асинхронного сервера).
- Вы можете не тратить ресурсы на вычисление абсолютного пути запрашиваемого модуля (это и есть основное место для потери производительности).
include_once
Поведение include_once идентично инструкции , с той лишь разницей, что если код из файла уже был один раз подключен, он не будет подключен и выполнен повторно. Это помогает избежать проблемы с переопределением функций, переменных и т.д. Чтобы лучше понять как это работает приведем пример:
<?php // определим функцию внутри файла add.php function add($x, $y) { return $x + $y; } ?>
В попытаемся выполнить следующий код:
<?php // подключаем два раза файл add.php include 'add.php'; include 'add.php'; echo add(5, 5); ?>
В результате будет получено сообщение об ошибке, так как функции переопределять нельзя. Чтобы избежать ошибок подобного рода, следует использовать инструкцию . Перепишем код в файле :
<?php // подключаем два раза файл add.php include_once 'add.php'; include_once 'add.php'; echo add(5, 5); ?>
PHP include vs. require
The statement is also used to include a file into the PHP code.
However, there is one big difference between include and require; when a
file is included with the statement and PHP cannot find it, the script
will continue to execute:
Example
<html>
<body>
<h1>Welcome to my home page!</h1>
<?php include ‘noFileExists.php’;
echo «I have a $color $car.»;?>
</body>
</html>
If we do the same example using the statement, the
echo statement will not be executed because the script execution dies after the
statement returned a fatal error:
Example
<html>
<body>
<h1>Welcome to my home page!</h1>
<?php require ‘noFileExists.php’;
echo «I have a $color $car.»;?>
</body>
</html>
Use when the file is required by the application.
Use when the file is not required and application should continue when file is not found.
PHP include Examples
Example 1
Assume we have a standard footer file called «footer.php», that looks like this:
<?phpecho «<p>Copyright © 1999-» . date(«Y») . » W3Schools.com</p>»;?>
To include the footer file in a page, use the statement:
Example
<html>
<body>
<h1>Welcome to my home page!</h1>
<p>Some text.</p><p>Some more text.</p><?php include ‘footer.php’;?>
</body>
</html>
Example 2
Assume we have a standard menu file called «menu.php»:
<?phpecho ‘<a href=»/default.asp»>Home</a> -<a href=»/html/default.asp»>HTML Tutorial</a> -<a href=»/css/default.asp»>CSS Tutorial</a> -<a href=»/js/default.asp»>JavaScript Tutorial</a> -<a href=»default.asp»>PHP Tutorial</a>’;?>
All pages in the Web site should use this menu file. Here is how it can be done
(we are using a <div> element so that the menu easily can be styled with CSS later):
Example
<html>
<body>
<div class=»menu»><?php include ‘menu.php’;?></div>
<h1>Welcome to my home page!</h1><p>Some text.</p><p>Some more text.</p>
</body>
</html>
Example 3
Assume we have a file called «vars.php», with some variables defined:
<?php
$color=’red’;
$car=’BMW’;
?>
Then, if we include the «vars.php» file, the variables can be used in the calling file:
Example
<html>
<body>
<h1>Welcome to my home page!</h1>
<?php include ‘vars.php’;
echo «I have a $color $car.»;?>
</body>
</html>
Абсолютные и относительные пути
При подключении файла в качестве его адреса можно указывать абсолютный или относительный путь.
Абсолютный путь включает в себя полный адрес файла от корня диска.
Пример:
Относительный путь содержит адрес только относительно текущей рабочей директории. Так если сценарий лежит в папке , то для подключения файла можно использовать такой путь:
Всегда предпочитай указывать относительные пути, чтобы сайт продолжал работать, если его переместят в другую папку.
Полезные константы
В PHP есть полезные встроенные константы, которые пригодятся для использования в пути к подключаемым файла.
— Полный путь к директории, в которой находится текущий сценарий — Полный путь к текущему сценарию
Зачем разделять и подключать php-сценарии
PHP-разработчики дробят весь исходный код проекта на отдельные сценарии, чтобы с ними проще было работать. Если бы пришлось писать весь код в одном файле, то такой сценарий стал бы просто необъятным и ориентироваться там стало решительно невозможно. Поэтому разделение кода на разные сценарии — это естественный способ бороться со сложностью.
Есть и ещё один положительный эффект от подобного деления. Если вынести повторяющиеся блоки кода в отдельные сценарии, то появится возможность повторно использовать один код в разных файлах и подключать его только по требованию. Хороший пример — это пользовательские функции. Очень удобно объявлять их в отдельном сценарии, а затем подключать там, где эти функции понадобятся.
include
Инструкция include позволяет подключать и присоединять к вашему PHP-сценарию другие сценарии. При запуске программы интерпретатор просто заменит инструкцию на содержимое подключаемого файла. Давайте посмотрим как это работает, создайте файл с именем и напишите внутри:
<?php $var1 = 'красный'; $var2 = 'яблоко'; ?>
Теперь создадим другой файл и назовем его к примеру , в котором мы подключим файл :
<?php // предполагается, что файл add.php находится в той же директории, // что и сам сценарий, поэтому мы не указываем путь к файлу include 'add.php'; echo "\$var1 = $var1<br> \$var2 = $var2" ?>
Как видно из примера инструкция присоединяет содержимое подключаемого файла, благодаря этому ваша программа получает доступ к другим переменным, функциям, классам и т.д.
Примечание: вы можете присваивать подключаемым файлам любые имена, но всегда добавляйте расширение , потому что при использовании другого расширения, злоумышленники могут запросить ваш файл, и веб-сервер вернет его текст. Это угроза безопасности, поскольку могут быть раскрыты пароли или принцип действия вашей программы, что дает лазейку злоумышленникам. Чтобы этого не происходило, подключаемые файлы должны обрабатываться интерпретатором PHP.
Подключение внутри функции
Если подключение файла происходит внутри функции, тогда весь код, содержащийся во включаемом файле, будет вести себя так, как будто он был определен внутри этой функции, т.е. код будет иметь локальную область видимости. Перепишем немного предыдущий пример:
<?php // код внутри файла add.php $var1 = 'красный'; $var2 = 'яблоко'; ?>
Теперь добавим функцию в :
<?php function foo() { // объявили $var1 глобальной переменной global $var1; include 'add.php'; echo "Внутри функции: $var1 $var2"; } foo(); echo "<br>В глобальной области: $var1"; ?>
Так как внутри функции мы объявили переменную глобальной, она становится также доступной и в глобальной области видимости.