php eval() 中的语句

statement inside php eval()

在提供使用 eval() 实现的挂钩点的 PHP 框架中,我试图从 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() 确实只计算 expressions 而不能计算 statements - 那么我该如何实现 continue /在 eval()?

中中断语句

您不能在 eval() 中使用 continuebreak 之类的语句来影响外部循环。

我建议使用变量。

$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
}';

恕我直言,这整件事闻起来有鱼腥味。该插件依赖于用于循环的特定变量,这是非常脆弱的。

continuebreakreturn 等影响程序控制流的关键字不能直接在eval 中使用以达到您想要的结果。 eval 是一个函数,函数不能改变调用它的代码的控制流,除非抛出异常。

由于 continue 仅表示 "skip to the next iteration of the loop",这等同于 "don't execute the rest of the code in this block",您可以重写代码以使块的其余部分以 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);
}

然而,这仍然只会影响您传递到框架中的代码的控制流。无法更改框架代码本身的控制流。

暂时搁置 evalcontinue 的机制,我认为有一个更基本的观点需要说明:编写 "plugs in" 的代码时到另一个系统,你只能做那个系统允许你做的事

如果钩子系统只是简单地执行你给它的代码(无论是通过eval,还是一个回调函数,或任何其他机制),你不能用它来控制主程序中的循环流等框架代码。

如果框架希望您这样做,它必须为您的插件提供一种机制,以向框架发回您想要它执行的操作的信号 - 您可以以特定方式注册插件,return 回调中的特定值,设置特定变量等

如果您不想直接修改框架,您唯一的选择就是向框架的作者请求这样的功能。