Объявление функций внутри других функций
Допустим, вы решили определить одну функцию, которая будет регистрировать другие функции.
Такое поведение не совсем типично, но, возможно, имеет свои преимущества и способы применения.
function init() {
function finish($resource) {
// некоторая работа по завершению всех операций со связанным ресурсом
}
$resource = null;
// некоторая работа, возможно создание ресурсов
return $resource; // возвращение какого-то результата
}
$resource = init();
finish($resource);
Объявление функций внутри методов
Определяете вы класс, методы, тела методов, и в один прекрасный момент вы, прочитав stackoverflow или reddit, и попробовав запустить это на 3v4l.org, осознаёте, что возможность, которую PHP интерпретатор предоставляет, является с одной стороны очень спорной, а с другой дает возможность определять какую-либо функциональность только по запросу.
class test {
function register() {
if (!function_exists('test_init')) {
function test_init() {
echo 'Initializing library'.PHP_EOL;
}
}
}
}
$test = new test;
$test->register();
test_init();
Этот код успешно выполняется на PHP 4.x (>=4.3.10), PHP 5 (>=5.0.5), PHP 7 и HHVM.
Видимо, такая функциональность кому-то была нужна, и ещё в 2005-м году был создан баг, описывающий данную функциональность.
P.S: В 2015-м году использовать глобальные функции уже совсем необязательно, а уж тем более определять вложенные, но эта возможность жива и скорее всего не скоро будет удалена из языка.
Комментарии (11)
Temirkhan
10.06.2015 23:42+4Объявлять функции внутри других функций, насколько я помню, плохая практика.
kaichou
11.06.2015 09:51+3Расскажите это программистам JS.
andrewnester
11.06.2015 09:57+18В JS видимость таких функций ограничена «родительской» функцией, а в php такая функция становится глобальной. Это большая разница
Andre_487
13.06.2015 01:40У JS и PHP активный обмен опытом: в PHP объявляют вложенные функции, в React пишут HTML среди кода
andrewnester
10.06.2015 23:52+2То, что вы описали, часто используется в компонентах Joomla например
Компонент должен работать и в 1.5 и в 2.5, но в 2.5 удалили функцию, которая была в 1.5 или ее переименовали, и она используется в этом компоненте
Для этого и пишутся там такие хаки, которые по требованию создают нужную функцию
Ничего в этом хорошего нет, но это ведь legacy code :)
tzlom
11.06.2015 00:02+6Подобный код часто встречается в библиотеках мечтающих о mbstring, в автолоадере проверяется наличие нужных mb_* функций и если что-то отсутствует — объявляется свой костылёк
Apfel
11.06.2015 15:06Должен покаяться: применял такую практику для array_map, usort и т.д., когда еще не было анонимных функций.
После их введения о таком забыл.
P.S.
Речь только о РНР.
ilyaplot
11.06.2015 21:33Как каз сегодня пришлось писать curl_reset внутри функции класса что бы заработал сторонний компонент. Что удобно, функция создается только в том случае, если не была определена. Так что функционал должен присутствовать.
maximw
Небольшая ошибка в первом куске кода.
wapmorgan Автор
Исправил на другое имя, т.к. не проверял код. Спасибо.