Анонимная функция с динамическим количеством аргументов/параметров

Итак, некоторое время назад я создал синтаксический анализатор для плагина jQuery Query Builder, который анализирует формулу в PHP-код, который возвращает некоторые вычисления на основе добавленных параметров, он может варьироваться от return $a + $b; до чего-то вроде

if($a == 'some_value' || $c == 'other_value') {
    return $something;
} else if($b == 'something' && $d == 'anything') {
    return $something_else;
} else {
    return $anything;
}

а может быть еще сложнее. Дело в том, что он создает это как строку, которую я затем передал другой функции, которая возвращает динамическую функцию, созданную с помощью create_function, но этот конструктор в PHP устарел с версии 7.2.0.

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

protected function createFunction($formula, &$data)
{
    $args = '';

    foreach($data as $key => $value) {
        $args .= '$' . $key . ', ';
    }

    return create_function(substr($args, 0, strlen($args) - 2), $formula);
}

Как видите, $formula — это динамический PHP-код, который я написал выше, а $data — это ассоциативный массив (обычно строка из базы данных). Любые идеи?

Редактировать: Забыл упомянуть, что проблема не в самой формуле, так как я могу просто использовать eval() для этого (я не беспокоюсь здесь о безопасности, так что все в порядке), просто я не уверен, как добавить динамическое количество параметров с именами динамических переменных.


person AwesomeGuy    schedule 07.08.2018    source источник


Ответы (1)


Вы можете воспользоваться анонимными функциями.

Я использовал eval в этом случае из-за вашего комментария:

Редактировать: забыл упомянуть, сама формула не является проблемой, так как я могу просто использовать для этого функцию eval() (здесь меня не волнует безопасность, так что все в порядке)

class Foo
{
    public function createFunction($formula, $args)
    {
        $func = function ($args) use ($formula) {
            foreach ($args as $key => $val) {
                $$key = $val;
            }
            return eval($formula);
        };
        return $func($args);
    }
}

$foo = new Foo;

$foo->createFunction('echo $a + $b;', ['a' => 1, 'b' => 2]);

живой пример вашего кода https://3v4l.org/HrMKN

person hassan    schedule 09.08.2018
comment
Это выглядит хорошо, я проверю это немного позже, а затем, вероятно, отмечу этот ответ как правильный. Спасибо - person AwesomeGuy; 09.08.2018
comment
дайте мне знать, если есть какие-либо проблемы - person hassan; 09.08.2018
comment
Хорошо, я проверил это, и это хорошо, кроме одной строки (на самом деле все хорошо, просто для моего случая мне нужно ее изменить), return $func($args); должен вернуть функцию, а не ее результат, поэтому следует вернуть $func; А в остальном все отлично, еще раз спасибо. :) - person AwesomeGuy; 09.08.2018