Двойное обертывание в PHP

В этой статье я расскажу о том, как делать двойное (ну или n-ое) обертывание некой функции в php 5.3 Вообще это может понадобиться для очень многих вещей: кэширование, логирование и т.д.

Задача.

Мы находимся в контроллере, в котором происходит итерация некой функции по месяцам. При этом в каждом экшене контроллера функция – разная. В тоже самое время мы хотим внедрить кэширование данных, которые выдают такие функции.

Представим себе, что мы находимся в контроллере, и там присутствует много вот такого кода:

Отчётливо видим повторение кода.
Теперь второй случай, который наверняка многим знаком.

И так в каждой функции, которая требует кэширование. Ух, сколько же можно сократить кода в проекте!)

Решение.

Будем использовать две обертки. Первая (внешнаяя) обертка (wrapper) будет оборачивать переданную функцию (fallback) итерируя её по месяцам. Вторая (внутренняя) обертка будет оборачивать целевую функцию в кэширующий слой. Если быть точным, то это будет выглядеть так: MonthWrapper ( CacheWrapper (Fallback) ) ). Т.е. для внешней обертки в качестве fallback передаётся не сама функция а вторая её обертка.

SomeController.php

Это обертка по месяцам (внешняя).

RepositoryFunction.php

А это вторая обертка (внутренняя) для кэширования.

Service.php

Теперь самое интересное, что обертки можно использовать и отдельно. Например только кэшировать.

Ссылки

http://habrahabr.ru/post/145317/
http://habrahabr.ru/company/mailru/blog/103983/

8 Comments

  1. А для чего передаются $rep, $fallbackForMonthWrapper по ссылкам (&) в конструкции use?

    1. Они используеются внутри замыкания: return $rep->monthWrapper($fallbackForMonthWrapper);

      1. Верно, но я к тому, что объекты всегда передаются по ссылки

        1. Хм, а можете ссылку кинуть? А то натыкаюсь на противоречивые сведения (1,2).

          1. Замете, что в обоих примерах переменные не объекты – а скалярные типы.

            В первой ссылке число $my_var = 0, а во второй строка $function = uniqid().

            Т.е. если в конструкции use используются не объекты и они могут меняться внутри тела замыкания, то их обязательно передавать по ссылке.

    1. Ок, спасибо за наводку. Ну собственно тогда амперсанды в данном случае вовсе не нужны.

Leave a Comment