
Комментарии 16
Спасибо, не знал. Действительно, полезно перечитывать документацию.
Но так все же зачем конкретно в колбэке для usort (приведенном в начале статьи) static? Просто по привычке (кабы не было чего)?
Спасибо за фидбек.
Этот коллбек вырван из контекста. Он как раз находился в методе класса ExampleTest , который показан на скрине чуть ниже по тексту (там где я сделал дамп и показал, что внутри анонимной функции мы действительно можем обратиться к this.
Получается если ты ведешь разработку на фреймворке, то так или иначе ты всё равно будешь находиться внутри класса (будь то контроллер, юзкейс, репозиторий, не важно). Выходит, что в таком случае это уместно использовать везде, где тебе не нужно обращаться к $this.
С другой стороны, если ты просто пишешь скрипт, то static никак не повредит. В целом можно в команде договориться о правиле вроде "Ставь везде static, убирай только там, где обращаешься к $this" (по аналогии с final напр.).
Ну даже в ExampleTest — нет там никакой утечки даже без static, разве не так?
Я бы даже сказал, что утечка будет в каких-то экзотических (синтетических, по большей части) случаях — вроде примера с LargeObject
Да, верно, как таковой проблемы в примере нет. А вот насчет синтетических или экзотических случаев я тут не совсем соглашусь. Из моей практики очень часто всплывало то, что "маловероятно" или "такого вообще никогда не произойдет". Особенно эта боль бывает когда обсуждают бизнес требования :) Но ладно, речь о другом. Так вот, введя правило для своей команды из моего предыдущего комментария, как мне кажется, мы избавляем себя от лишней головной боли и можем не думать о том "может ли здесь произойти утечка".
В таком случае она никогда не произойдет, а все места где может — они сделаны осознанно и их легче проконтролировать.
Но здесь каждый разработчик и команда должны сами выбирать, как с этим работать, главное знать, что такая ситуация возможна :)
Интересно, что в Kotlin подобная функциональность реализована явно с помощью receiver'ов. Непонятно, зачем неявно привязывать лямбды к this. У PHP снова свой собственный путь:)
А PHP 5.3 (если не путаю версию в котором завезли \Closure) с этим функционалом выпущен в 2009.
И у кого тут «свой собственный путь»?
Какая короткая и какая полезная статья! Спасибо огромное за повышение моего скилла!
Чтобы не оценивать «большинство случаев» и не проверять код на «искусственность/неискусственность», разумно принять предлагаемое правило: всегда использовать static для анонимных функций, когда не нужен доступ к $this.
Автор напоминает (спасибо!), как работает ключевое слово в функциях-замыканиях, и говорит о том, что без static в замыканиях можно случайно нарваться на неоправданные затраты памяти. Вы каждый раз (!) избегаете риска утечки памяти с ключевым словом static в случаях необращения к $this в замыканиях. Зачем рисковать?!
Расшифруйте, пожалуйста, в чем состоит ваше возражение? Помните: отвергая, предлагай? Почему бы вам не предложить собственные рекомендации по теме?
Да, интересное поведение. И как заметил @marshinov никакой логикой не обусловленное. Просто задокументированный кастыль. Ладно, если бы внутри замыкания использовался $this, тогда ладно, вопросов нет. Но без $this...
<?php
class Example {
public function getClosure() {
return static function() {
return 1;
};
}
}
$example = new Example();
xdebug_debug_zval('example');
$closure = $example->getClosure();
xdebug_debug_zval('example');
$ php test.php
example: (refcount=1, is_ref=0)=class Example { }
example: (refcount=1, is_ref=0)=class Example { }Однако, если удалить static из кода, то refcount на втором вызове xdebug_debug_zval покажет 2, т.е. уже две ссылки будут указывать на инстанс класса Example.
$ php test.php
example: (refcount=1, is_ref=0)=class Example { }
example: (refcount=2, is_ref=0)=class Example { }
Зачем нужен static при объявлении анонимных функций?