| |
матриваемой
проблемой, по достоинству оценят затраченные усилия, особенно если их сце-
нарии состоят из десятков файлов и библиотек.
Помните, что при помощи include или require нельзя один и тот же файл загру-
жать дважды (как это часто бывает, если один модуль вызывает другой, но
програм-
ма об этом "не знает" и еще раз подключает первый — опять же, стандартный слу-
чай). В самом деле, если в этом файле находится, к примеру, описание
какой-нибудь
функции, то при следующем его включении PHP выдаст ошибку: повторное объявле-
ние функции. Конечно, последняя проблема полностью решается подстановкой
include_once вместо include, что работает, кстати, только в PHP версии 4.
Отсюда мы можем сформулировать главные два требования.
r Механизм загрузки модуля должен сам решать, в каком каталоге располагается
модуль, независимо от того, где выполняется сценарий. В любой программе воз-
можность загрузить указанный по имени модуль должна быть легко осуществима.
Мы хотели бы, чтобы это было так же просто, как мы делаем это с обычными
файлами из текущего каталога при помощи include.
r Один и тот же модуль не должен загружаться дважды, даже если программа по-
пытается это выполнить.
К слову сказать, оба требования реализованы, например, в языке Perl.
Как я уже говорил, мы можем написать нужную нам "инструкцию", которая будет
загружать модуль с применением указанных принципов прямо на PHP. Назовем ее
Uses() и оформим в виде функции.
Далее для краткости модулем на PHP я буду называть файл (например, с рас-
ширением phl), содержащий некоторые общеупотребительные функции, кон-
станты и переменные, а также исполняемую часть, которая запускается при
первой (и только первой) загрузке модуля.
Библиотекарь
Ту часть кода, которая будет содержать функцию Uses() (а мы реализуем ее именно
в виде функции) и другие функции, нужные для загрузки модулей, назовем библио-
текарем. Этот библиотекарь, очевидно, сценарию придется загружать первым, а ка-
ким именно образом, мы поговорим чуть позже.
Глава 29. Модульность программы. Написание "библиотекаря"
399
Теперь немного о том, как мы будем реализовывать Uses(). Это довольно несложно.
Помните, я подчеркивал, что поскольку PHP является интерпретатором, то на нем
осуществимы такие приемы, как описание функций внутри функций и многое другое.
Так мы и сделаем: функция Uses() вначале будет проверять, не загружался ли уже
модуль с таким именем, затем искать затребованный модуль в специальных "катало-
гах для модулей", фиксировать во внутреннем массиве факт, что указанный файл
за-
гружен, и, наконец, вызывать include_once для файла с модулем. Кроме того, на
время загрузки текущий каталог будет сменяться на тот, в котором находится
модуль,
чтобы стартовые части всех модулей запускались в "своих" каталогах. Это как раз
та
возможность, которая отсутствует в Perl, и которая оказывается довольно удобной
на
практике.
Раз библиотекарь всегда подключается к программе в первую очередь, разумно
дове-
рить ему выполнение еще некоторых действий.
r Поместим в файл библиотекаря функции, чаще всего необходимые почти каждому
сценарию. Таким образом, мы как бы "расширим" набор встроенных в PHP функ-
ций. Однако помните, что встроенные функции переопределять все же нельзя,
можно лишь создавать новые с уникальными именами.
r Библиотекарь, как никто другой, должен приложить максимум усилий, чтобы сде-
лать сценарии переносимыми с одной платформы на другую. Для нас это будет
заключаться в корректировке некоторых переменных, которые PHP создает перед
выполнением программы. Первым кандидатом на такую правку будет
$SCRIPT_NAME (а также одноиме
|
|