|
ользоваться
следующей функцией — она работает гораздо быстрее:
function Factor($n)
{ for($f=1; $n>1; $n--) $f*=$n;
return $f;
}
Вложенные функции
Стандарт PHP не поддерживает вложенные функции. Однако он поддерживает нечто,
немного похожее на них. Вместо того чтобы, как и у переменных, ограничить
область
видимости для вложенных функций своими "родителями", PHP делает их доступны-
ми для всей остальной части программы, но только с того момента, когда
"функция-
родитель" была из нее вызвана. Позднее, в части V книги, мы увидим, что этот
(ка-
залось бы) недочет оказывается довольно удобным способом для написания
библиотек функций на PHP.
Итак, "вложенные" функции выглядят следующим образом (листинг 11.13):
Листинг 11.13. Вложенные функции
function Parent($a)
{ echo $a;
function Child($b)
{ echo $b+1;
return $b*$b;
}
return $a*$a*Child($a); // фактически возвращает $a*$a*($a+1)*($a+1)
}
// Вызываем функции
Parent(10);
Часть III. Основы языка PHP 196
Child(30);
// Попробуйте теперь ВМЕСТО этих двух вызовов поставить такие
// же, но только в обратном порядке. Что, выдает ошибку?
// Почему, спрашиваете? Читайте дальше!
Мы видим, что нет никаких ограничений на место описания функции — будь то гло-
бальная область видимости программы, либо же тело какой-то другой функции. В то
же время, напоминаю, что понятия "локальная функция" как такового в PHP все же
(пока?) не существует.
Каждая функция добавляется во внутреннюю таблицу функций PHP тогда, когда
управление доходит до участка программы, содержащего определение этой функции.
При этом, конечно, само тело функции пропускается, однако ее имя фиксируется и
может далее быть использовано в сценарии для вызова. Если же в процессе
выполне-
ния программы PHP никогда не доходит до определения некоторой функции, она не
будет "видна", как будто ее и не существует — это ответ на вопросы, заданные
внутри
комментариев примера.
Давайте теперь попробуем запустить другой пример. Вызовем Parent() два раза
подряд:
Parent(10);
Parent(20);
Последний вызов породит ошибку: функция Child() уже определена. Это произош-
ло потому, что Child() определяется внутри Parent(), и до ее определения управ-
ление программы фактически доходит дважды (при первом и втором вызовах
Parent()). Поэтому-то интерпретатор и "протестует": он не может второй раз
доба-
вить Child() в таблицу функций.
Для тех, кто раньше программировал на Perl, этот факт может показаться ужа-
сающим. Что ж, действительно, мы не должны использовать вложенные функ-
ции PHP так же, как делали это в Perl.
Условно определяемые функции
Предположим, у нас в программе где-то устанавливается переменная $OS_TYPE в
значение win, если сценарий запущен под Windows 9x, и в unix, если под Unix.
Как
известно, в отличие от Unix, в Windows нет такого понятия, как владелец файла,
а
значит, стандартная функция chown() (которая как раз и назначает владельца для
указанного файла) там просто не имеет смысла. В некоторых версиях PHP для
Windows ее может в этой связи вообще не быть. Однако, чтобы улучшить переноси-
мость сценариев с одной платформы на другую (без изменения их кода!) можно на-
писать следующую простую "обертку" для функции chown() (листинг 11.14):
Глава 11. Функции и области видимости 197
Листинг 11.14. Условно определяемые функции
if($OS_TYPE=="win")
{ // Функция-заглушка
function MyChOwn($fname,$attr)
{ // ничего не делает
return 1;
}
}
else
{ // Передаем вызов настоящей chown()
|
|