Лямбда-функции, замыкания и классы PHP 5.3
В WordPress повсеместно используется механизм функционалов (и callback аргументов соответственно, хотя – очень грубое и ограниченное “пояснение”). В результате мы получаем избыточный код (далее приведу пример). Возникла надежда, что с выходом PHP 5.3 лямбда функции решат проблему, но не тут-то было… Разберёмся.
Как и обещал, приведу сначала пример избыточного, навязанного функционалами и механизмом событий (action и filter) WordPress:
add_settings_section( self::$_namespace . '_location_options', __('Location of your opensearch.xml file', self::$_domain), array(__CLASS__, 'option_location_options_description'), self::$_namespace . '_options_page' ); ... public static function option_location_options_description() { ?> <p><?php _e('You can select location of your opensearch.xml file and his url, or leave automatic detection.', self::$_domain); ?></p> <?php }
И при написании простейшего плагина подобного избыточного кода будет масса. Мы вынуждены описывать методы или функции, хотя прекрасно знаем, что используем их однажды.
С выходом PHP 5.3 появилась надежда на то, что механизм лямбда функций и замыканий избавит нас от подобной избыточности. Надежда выражалась в том, что приведённый выше пример можно будет переписать следующим образом:
add_settings_section( self::$_namespace . '_location_options', __('Location of your opensearch.xml file', self::$_domain), function () { ?> <p><?php _e('You can select location of your opensearch.xml file and his url, or leave automatic detection.', self::$_domain); ?></p> <?php }, self::$_namespace . '_options_page' );
Спешу Вас огорчить – код нерабочий. Лямбда функции работают, и замыкания – также работают. Но созданная через замыкание функция не становится методом класса! Да, при создании замыкания в методе объекта (не статическом методе класса), $this
доступна в пределах замыкания даже без явного “импорта”, но код замыкания имеет права доступа к методам и полям объекта как внешний по отношению к классу код! то есть – только к публичным членам!
Ещё хуже, если мы создаём замыкание в статическом методе класса. Как Вы уже поняли, self::
в пределах замыкания использовать не удастся. Именно поэтому вышеприведённый код “не работает”.
Честно говоря, не понял, в связи с чем разработчики PHP не рассматривают замыкание, созданное кодом методов класса как метод класса, но при этом неявно связывают замыкание с $this
. Явно напрашивается “внедрение” замыкания в класс с правом доступа к private и protected членам класса, использованием self::
и $this->
.
P.S. Если Вы не используете классы PHP для создания пространства имён для Вашего плагина WordPress, тогда Вам действительно поможет сократить код и сделать его более “прозрачным” использование PHP 5.3 и его лямбда функций и замыканий. Если же Вы используете классы – Вам PHP 5.3 не поможет (а я так надеялся, скачал, поставил – и такой облом).
Будем надеяться, что PHP 5.4 наконец-то принесёт полноценные замыкания и в ООП программирование на PHP. Пока что “вывесил” это баг: http://bugs.php.net/bug.php?id=53610. Надеюсь, получу положительное решение проблемы.
Отзывы » (1)
RSS комментарии
Обратная ссылка
Сегодня пробежал ещё один комментарий на близкую тему.
Так что мы не одиноки с проблемами замыканий в PHP.