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()
中使用 continue
或 break
之类的语句来影响外部循环。
我建议使用变量。
$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
}';
恕我直言,这整件事闻起来有鱼腥味。该插件依赖于用于循环的特定变量,这是非常脆弱的。
continue
、break
和return
等影响程序控制流的关键字不能直接在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);
}
然而,这仍然只会影响您传递到框架中的代码的控制流。无法更改框架代码本身的控制流。
暂时搁置 eval
和 continue
的机制,我认为有一个更基本的观点需要说明:编写 "plugs in" 的代码时到另一个系统,你只能做那个系统允许你做的事。
如果钩子系统只是简单地执行你给它的代码(无论是通过eval
,还是一个回调函数,或任何其他机制),你不能用它来控制主程序中的循环流等框架代码。
如果框架希望您这样做,它必须为您的插件提供一种机制,以向框架发回您想要它执行的操作的信号 - 您可以以特定方式注册插件,return 回调中的特定值,设置特定变量等
如果您不想直接修改框架,您唯一的选择就是向框架的作者请求这样的功能。
在提供使用 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()
中使用 continue
或 break
之类的语句来影响外部循环。
我建议使用变量。
$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
}';
恕我直言,这整件事闻起来有鱼腥味。该插件依赖于用于循环的特定变量,这是非常脆弱的。
continue
、break
和return
等影响程序控制流的关键字不能直接在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);
}
然而,这仍然只会影响您传递到框架中的代码的控制流。无法更改框架代码本身的控制流。
暂时搁置 eval
和 continue
的机制,我认为有一个更基本的观点需要说明:编写 "plugs in" 的代码时到另一个系统,你只能做那个系统允许你做的事。
如果钩子系统只是简单地执行你给它的代码(无论是通过eval
,还是一个回调函数,或任何其他机制),你不能用它来控制主程序中的循环流等框架代码。
如果框架希望您这样做,它必须为您的插件提供一种机制,以向框架发回您想要它执行的操作的信号 - 您可以以特定方式注册插件,return 回调中的特定值,设置特定变量等
如果您不想直接修改框架,您唯一的选择就是向框架的作者请求这样的功能。