РНР 5 в подлиннике

Страница 149 из 554


302

Часть III. Основы языка РНР

Функция file о, которую мы пока не рассматривали, целиком считывает файл с указанным именем (или с указанным полным URL) и возвращает все его строки в виде одного массива.

Мы намеренно упростили функцию virtual о, чтобы пока не использовать функции по работе с регулярными выражениями, которые еще не были нами описаны. Так, попытка применения заглушки virtual () с относительным UR! (не начинающимся с символа /) приведет к ошибке.

Знатоки языка С могут заметить в приеме условно определяемых функций разительное сходство с директивами условной компиляции этого языка: tifndef, #eise и tendif. Действительно, аналогия почти полная, за исключением того факта, что в С эти директивы обрабатываются во время компиляции, а в РНР — во время выполнения. Что ж, на то он и интерпретатор, чтобы позволять себе интерпретацию.

Г Примечание J

Возможность создавать условно определяемые функции сильно подрывает веру в РНР как в истинный транслятор. Как вообще можно устроить транслятор так, чтобы он правильно обрабатывал подобные вещи? Мы не знаем. Надеемся, что разработчики РНР нашли-таки способ, и условно определяемые функции транслируются вместе со всей программой, а не на этапе исполнения, как это было в РНР версии 3. Однако полной уверенности в этом нет, а документация по этому поводу молчит (пока).

Мы отнюдь не случайно заключили последние два слова названия этого раздела в кавычки — дело в том, что как таковая передача функции по ссылке в РНР не поддерживается. Однако т. к. это слишком часто может быть полезным, в РНР есть понятие "функциональной переменной". Легче всего его можно рассмотреть на примерах:

function A($i) { echo "Вызвана A($i)\n"; }

function B($i) { echo "Вызвана B($i)\n"; }

function C($i) { echo "Вызвана C($i)\n"; )

$F = "A"; // или $F = "В" или $F = "C"

$F(303); // вызов функции, имя которой хранится в $F

Второй пример носит довольно прикладной характер. В РНР есть такая стандартная функция — uasorto, которая сортирует ассоциативный массив, причем критерием сравнения для элементов этого массива служит функция, чье имя передано вторым параметром. Мы будем рассматривать данную функцию позже, а сейчас приведем простой пример:

// Сравнение без учета регистра символов строк function FCmp($a, $b) {

return strcmp(strtolower($a), strtolower($b));

}

$riddle = array("g"=>"Not", "o"=>"enough", "d"=>"ordinariness"); uasort($riddle, "FCmp"); // Сортировка без учета регистра символов.

Передача функций "по ссылке"

Гпава 14. Функции и области видимости

303

Здесь функция, имя которой указано вторым параметром uasorto, должна иметь два аргумента, являющиеся сравниваемыми значениями в массиве.

В общем случае, функциональная переменная — это всего лишь переменная-строка, содержащая имя функции, и ничего больше. Поскольку в РНР нет такого понятия, как области видимости для функций (есть только области видимости для локальных переменных), то конфликтов это не порождает — одному имени может соответствовать не более одной функции. Такой подход, на наш взгляд, не очень хорош, но он действительно работает, и это главное.

Использование call_user_func()

Синтаксис $f{параметры) удобен и нагляден, однако в большинстве программ рекомендуется идти другим путем — вызывать стандартную функцию caii_user_func(), например:

function A($i) { echo "Вызвана A($i)\n"; }

function B($i) { echo "Вызвана B($i)\n"; }

function C($i) { echo "Вызвана C($i)\n"; }

$F = "A"; // или $F = "В" или $F = "C"

call_user_func($F, 101); // вызов функции, имя которой хранится в $F

Функция caii_user_func() делает следующее: она запускает на выполнение подпрограмму, имя которой указано в ее'первом параметре, и передает ей аргументы, заданные в остальных.

Чем же объясняется такой совет? Дело в том, что в качестве первого параметра функции может быть передано не только строковое значение, но и массив из двух элементов, содержащий:

П имя класса (или ссылку на объект класса);

П имя метода класса.

Вероятно, вы уже догадались, что речь идет об объектно-ориентированном программировании, а функция caii_user_func() позволяет вызывать не только обычные функции, но также и методы объектов. Мы отложим детали и разъяснения до части V.

Использование call_user_func_array()

Функция caii_user_func_array() предназначена для вызова подпрограмм, когда на момент вызова точно неизвестно, сколько именно аргументов им следует передать. Ее описание выглядит следующим образом:

mixed'call_user_func_array(string $имя_функции, array ^аргументы)

В отличие от caii_user_func(), параметры вызываемой подпрограмме передаются не последовательно, а в виде одного-единственного списка.

Для примера напишем функцию, которая распечатывает свои аргументы на отдельных строках, предваряя их указанным числом пробелов (может пригодиться для вывода различной информации "лесенкой"). Вспомним, что построчный вывод у нас




  Hostland.Ru

 «Бесплатный хостинг Hostland.Su» © 2006