Как в Php/Laravel создавать функции для отдельных записей?

170
08 марта 2022, 05:10

Не знал как конкретнее назвать топик, так что извеняйте.

На данный момент я разрабатываю систему, где можно самому создать свой чатбот себе на сайт.

Появилась потребность в добавлении дополнительного функционала для одного уже существующего чатбота, а если быть точным - надо добавить специальные фильтры для пользовательского ввода. К примеру, для одного чатбота надо фильтр на "Номер кредитной карты в Латвии" - чтобы когда пользователь вводил неверный номер карточки, ему выводилась ошибка. Остальным чатботам такой функционал не нужен".

На данный момент фильтры работают так: пользователь ввел текст, а он обрабатывается нужным REGEX (регулярным выражением) из базы данных. Но ведь будут случаи, когда REGEX-ом не обработаешь некоторые данные.

Вопрос, как с точки зрения чистого кода это лучше сделать? Кроме банального if chatbot_id == x { filterLatvianCreditCard(); } в голову ничего не приходит. Желательно чтобы процесс отсоеденения этого "дополнения" был простым.

Код пишу на Laravel.

Answer 1

Это вопрос архитектуры и масштабирования. Обычно подобные проблемы решаются применением паттернов проектирования.

Если я правильно понял вашу проблему, то самое простое решение на мой взгляд выглядит так:

Создаем модель бота Bot и модель фильтра BotFilter

Один бот может поддерживать несколько фильтров. В базе храним название фильтра, каждому фильтру соответствует своя реализация.

Все фильтры реализуют один интерфейс.

interface Filter {
    public function run(array $data);
}
class CreditCardFilter implements Filter {
    public function run(array $data)
    {
        if($this->isValid($data))
            ....
    }
}

Так же понадобиться фабрика для получения объекта фильтра по названию из бд.

class FilterFactory {
    public static function getInstance(BotFilterModel $model): Filter {
        if($model->getName()==='credit_card_filter')
            return new CreditCardFilter();
        elseif ($model->getName()==='name_filter')
            return new NameFilter();
        else
            return new DefaultFilter();
    }
}

Таким образом, код обработки будет выглядеть примерно так:

$bot = Bot::query()->find(100); //получаем модель бота из бд
$botFilters = $bot->getFilters(); //по связи получаем список фильтров
foreach ($botFilters as $botFilter) {
    FilterFactory::getInstance($botFilter)->run($data);
}

То есть применяем все фильтры, которые указаны в настройках бота.

Таким образом любому боту можно добавлять/убирать фильтры. Все фильтры имеют свою реализацию и легко дополняются/расширяются.

Так же рекомендую обратить внимание на паттерн цепочка обязанностей и реализацию pipeline в laravel.

READ ALSO
Сделать number_format для decimal

Сделать number_format для decimal

Дело в том, что я вывожу число 10000000000000000000000000000000 из базы, после обработки функцией number_format оно превращается в 9999

98
Если нету слова, то не выводить

Если нету слова, то не выводить

Как выводить только эл-ты, у которых встречается слово IMDB

110
Код продолжает работать после ошибки 504 Gateway Time-out

Код продолжает работать после ошибки 504 Gateway Time-out

Бот не возвращает заголовков, но продолжжает работатьТак я выполняю очень долгий скрипт, и работает стабильно

161