Способ организации сложной php-функции

20-03-2026Время чтения ~ 3 мин.PHP 7

Иногда нужно сделать php-функцию, которая будет содержать сложную логику, html-вывод и т.п. Например вывод главной страницы админ-панели представляет собой последовательные блоки «Черновики», «Последние записи», «Последние комментарии» и т.д.

Способ организации сложной php-функции

Схематично это может выглядеть примерно так:

function my() {
    // 1. Подготовка общих данных
    // 2. Подготовка данных 1-го блока
    // 3. Подготовка данных 2-го блока
    // 4. и т.д. 

?>
<!-- html-вывод 1-го блока -->
<!-- html-вывод 2-го блока -->
<!-- прочий html-вывод -->

<!-- например STYLE -->
<!-- например SCRIPT -->

<?php 
    // Завершающая часть php-кода
}

С точки зрения теории, эту функцию следует разбить на несколько отдельных, где каждая будет заниматься только своей задачей. Например myBlock1(), myBlock2(), myBlockStyle(), myBlockCSS() и т.п.

Минус этого подхода в том, что вместо одной функции мы сразу получаем множество других.

Другой альтернативой может быть переход от функции к php-классу. Поскольку класс по сути это своя область видимости, то внутри можно сделать произвольное количество методов. Это хорошее решение.

Однако, давайте представим себе, что мы хотим для конечного пользователя оставить именно функцию, а не класс. Например пользователь должен использовать именно my(), а не $my = new My(); ....

Чтобы использовать такой подход придётся сделать что-то вроде такого:

function my() { 
    $helper = new MyHelper();
    // дальше работаем с объектом $helper
}

class MyHelper {
   ...
}

Что здесь произошло? Мы как бы создали взаимную связку функция-класс, где функция — это точка вызова, а класс — фактически исполняемая часть.

Такой подход часто используется, но, опять же, не лишен недостатка. Самый главный это то, что нужно как-то продумать схему именования классов, а также решить вопрос с автоподключением класса, особенно если используется PSR4. В большинстве случаев, программисты выносят класс в отдельный файл, что создаёт ещё одну сущность. А это именно то, чего мы стараемся избежать.

Выход заключается в использовании анонимных классов. В PHP анонимные классы можно создавать прямо в функциях, что позволяет спрятать всю реализацию строго в пределах самой функции. Плюсом такого подхода будет еще и то, что для пользователя нет никакой возможности вызвать внутренний класс функции, а сам класс не размывает ни область видимости, ни создаёт проблем с именованием и размещением.

Вот так это может схематично выглядеть:

function my() {
    // 1. Подготовка общих данных

    // 2. Анонимный класс, который скроет реализацию
    $helper = new class () {
        // делаем всё как в обычном классе
        public int $countPages;

        public function out1() {
            // ...
        }

        public function out2() {
            // ...
        }
    };

    // 3. Получение данных 1-го блока
    $out1 = $helper->out1();

    // 4. Получение данных 2-го блока
    $out2 = $helper->out2();

    // 5. Например получение поля/свойства из класса
    $countPages = $helper->countPages;

?>
<!-- html-вывод 1-го блока с использованием $out1 -->
<!-- html-вывод 2-го блока с использованием $out2 -->
<!-- прочий html-вывод -->

<!-- например STYLE -->
<!-- например SCRIPT -->

<?php 
    // Завершающая часть php-кода
}

Поскольку код мы организуем в классе $helper, то можно спокойно разделить его на удобные методы, поля/свойства и т.д. Теперь код становится намного удобней для поддержки и понимания.

Похожие записи
Оставьте комментарий!