Периодически сталкиваюсь с ситуацией, когда в админке сайта вместо пачки стандартных настроек "на все случаи жизни" (в формате галочек, селектов и текстовых полей) гораздо проще (и для пользователя приемлемо) оставить место для ввода небольшого куска кода, которым он сможет реализовать любую логику.
Ну, например, типовая ситуация - универсальная система управления способами доставки для интернет-магазина. Есть сущность "служба доставки", экземплярами которой являются различные службы доставки, и каждая со своей логикой тарификации... У одних стоимость доставки считается как "минимальная стоимость + доп.вес х цена доп.веса", у других - фикс, но зависит от города, у третьих - нелинейная сетка типа "0..1кг, 1..5кг, 5..25кг и т.п.", у четвертых - система наценок за определенный тип товара, и т.п. И при подключении очередного хитрого доставщика, приходится лезть в код и добавлять поддержку новых понятий, создавать для них особые настройки, и т.п.
Понятно, что "по феншую" надо вывести универсальный набор параметров, подходящий для любой логики, но во-первых, это неоправданное усложнение, а во-вторых - всеравно найдется очередной хитрый болт с левой резьбой, который вылетит за рамки, поэтому порой проще создать создать набор настроек для стандартной логики расчета, а для всего "за рамками" оставить одно тектовое поле, где подкованный менеджер сможет просто ввести кусок кода, и реализовать любую хитрую логику.
Задача - обеспечить возможность настройки любой новой логики для нового перевозчика "из админки", без вмешательства в код. НО! при этом соблюсти безопасность при выполнении этого кода, и ограничить его (кода) возможности исключительно приемом входных параметров (данные о заказе, товарах, доставке и т.п.) и возвратом результата в стандартном виде (ну, например, одного числа - итоговой стоимости доставки).
Собственно, вопрос: наверняка, есть какие-то готовые инструменты для подобной задачи.
Какие варианты приходят на ум:
- php eval - укажу здесь просто для полноты списка, т.к. сразу отметается по соображениям безопасности (хотя, может есть способы запускать eval в песочнице и ограничить его влияние на внешнюю среду?
- smarty - уже лучше, если закрутить все гайки безопасности; правда, требование "вернуть только число при рендеренге" и запрет на php-вызовы сильно вредят читабельности, но по крайней мере, это уже вариант...
А на что еще стоит посмотреть?
во многих языках для таких случаев используют скриптовый язык LUA.
например дизайнеры игр на нем скриптуют игровые события.
в пхп есть экстеншен php.net/manual/ru/book.lua.php либо можно чисто на пхп такой интерпретатор поискать.
такое решение позволит создать необходимую изоляцию и довольно понятный и дает большие возможности.
хотя по правде говоря может показаться избыточно, особенно если возможности нужны не супер сложные.
в мире пхп в большинстве случаев хватает библиотеки symfony expression language
также обеспечивает изоляцию но весь код должен ограничиваться одним выражением.
UPD первое решение может показаться сложным (нужно еще и lua знать) а второе ограниченным. однажды например писал на пхп интепретатор excel-like формул. этот интепретатор формулы компилировал в пхп код, поэтому при исполнении это было довольно быстро. модуль получается конечно сложный, изоляция также полная, делал комбинируя код из symfony expression language и из твига, код в них довольно похожий, похоже от одних создателей.
часто в небольших проектах конечно используют как раз php eval, если админка доступна только владельцу сайта. это просто, удобно и полнофункционально, но не безопасно (и с этим ничего уже не сделать). любой кто получит случайный доступ к админке сможет выполнять любой код на сервере.
Александр Х: для ваших задач лучше всего попробовать уложится в symfony expression language.
это и безопасно и удобно. скриптовый язык удобный и понятный. все остальное "для информации"
Александр Х: нет, для таких целей тернарный оператор только.
вот описанием всех фич синтакиса symfony.com/doc/current/components/expression_lang...
любое выражение в нем это реально одно выражение которое чтото должно вернуть, без промежуточных переменных.
ну кстати, там свои функции вроде можно подключать... смотрел пока не внимательно, но вроде как можно будет зарегистрировать чтото вроде myswitch(bool1, value1, bool2, value2, ...), только пока не понял, как там с произвольным колвом аргументов дела... на первый взгляд - можно, но надо вникать...
Александр Х: по поводу функций насколько я помню он не анализирует параметры функции, а просто вызовет ее со всеми указанными аргументами, так что на 99% это должно сработать.
Понятно, что "по феншую" надо вывести универсальный набор параметров, подходящий для любой логики
Вы не можете предусмотреть все, по этому заморачиваться со сверх универсальными вещами - обычно не к добру.
обеспечить возможность настройки любой новой логики для нового перевозчика "из админки", без вмешательства в код
Это возможно только в случае, если "любая задача" - это одна из реализованных задач.
при этом соблюсти безопасность при выполнении этого кода
Если хотите по секьюрному - ни каких eval, или тому подобных штук. Вам придется создать некий свой язык, который будет заточен под ваше окружение и стек задач. Вполне возможно это будет некий набор связных данных, с графическим представлением в виде диаграмм.
наверняка, есть какие-то готовые инструменты для подобной задачи
Нанимается инженер, который решает задачи изменения ПО под ваши нужды.
А на что еще стоит посмотреть?
На переосмысление задачи. Сейчас вы на пороге выстрела себе в ногу.