оператор внутри php eval () - PullRequest
       9

оператор внутри php eval ()

0 голосов
/ 31 октября 2019

В среде PHP, которая предоставляет точки подключения, реализованные с использованием eval (), я пытаюсь прервать или продолжить цикл из вызова eval (). Это то, что я пытаюсь

Фреймворк циклов типа

...
for( $i = 0; $i < 10; $i++ ) {
    // framweork code here ...
    eval( $plugin_code );
    // framweork code here ...
}
...

$ plugin_code содержит PHP-код - в данном примере

if( $i == 5 ) {
    continue;
}

Это приводит к этой ошибке

PHP Fatal error:  'continue' not in the 'loop' or 'switch' context

Если верно, что eval () оценивает только выражения и НЕ МОЖЕТ оценить операторов - тогда как я могу реализовать операторы continue / break внутриEval ()?

Ответы [ 3 ]

2 голосов
/ 01 ноября 2019

Оставляя на мгновение механику eval и continue, я думаю, что есть более фундаментальный момент, который нужно сделать: при написании кода, который «подключается» к другой системе, вы можете делать только то, чтоэта система позволяет вам делать .

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

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

Если вы не хотите напрямую модифицировать фреймворк, ваш единственный вариант - запросить такойфича от автора фреймворка.

0 голосов
/ 31 октября 2019

Ключевые слова, такие как continue, break и return, которые влияют на поток управления программой, нельзя использовать непосредственно внутри eval для достижения желаемого результата. eval - это функция, и функция не может изменить поток управления кода, который ее вызывает, кроме как путем генерирования исключения.

Поскольку continue просто означает «перейти к следующей итерации цикла»", и это эквивалентно" не выполнять остальную часть кода в этом блоке ", вы могли бы переписать свой код, чтобы вместо этого сделать остаток блока условным для оператора if. Если код выглядит как

for( $i = 0; $i < 10; $i++ ) {
    if( $i == 5 ) {
        continue;
    }
    // do more things
}

, его можно легко переписать как

for( $i = 0; $i < 10; $i++ ) {
    if( $i != 5 ) {
        // do more things
    }
}

, и теперь он имеет форму, которая может быть eval 'd:

// your code
$plugin_code = 'if( $i = 5 ) {
    // do more things
}';

// framework code
for( $i = 0; $i < 10; $i++ ) {
    eval($plugin_code);
}

Однако это все еще влияет только на поток управления кода, который вы передаете в платформу. Невозможно изменить поток управления самого кода платформы.

0 голосов
/ 31 октября 2019

Вы не можете использовать такие выражения, как continue или break в eval(), чтобы повлиять на внешний цикл.

Я предлагаю использовать переменную.

$plugin_code = 'if( $i == 5 ) {
    $continue = true;
}';

$continue = false;
for( $i = 0; $i < 10; $i++ ) {
    eval( $plugin_code );
    if ($continue) {
        continue;
    }
    // other code
}

ЕслиВы также хотите пропустить остальную часть кода плагина, он должен поместить этот код в блок else.

$plugin_code = 'if( $i == 5 ) {
    $continue = true;
} else {
    // other code
}';

ИМХО, все это пахнет подозрительно. Плагин зависит от конкретной переменной, используемой для цикла, которая довольно хрупкая.

...