Reputation: 843
In a PHP framework which provides hookpoints that are implemented using eval() I am trying to interrupt or continue a loop from within an eval() call. This is what I am trying
The framework loops like
...
for( $i = 0; $i < 10; $i++ ) {
// framweork code here ...
eval( $plugin_code );
// framweork code here ...
}
...
$plugin_code contains PHP-code - in this sample case
if( $i == 5 ) {
continue;
}
It results in this error
PHP Fatal error: 'continue' not in the 'loop' or 'switch' context
If it is true that eval() only evaluates expressions and can NOT evaluate statements - then how can I implement the continue / break statements inside an eval()?
Upvotes: 1
Views: 625
Reputation: 51037
Keywords like continue
, break
and return
which affect the control-flow of the program cannot be used directly inside eval
to achieve the result you want. eval
is a function, and a function cannot change the control-flow of the code which calls it, except by throwing an exception.
Since continue
simply means "skip to the next iteration of the loop", and this is equivalent to "don't execute the rest of the code in this block", you could rewrite your code to make the rest of the block conditional on the if
statement instead. If the code looks like
for( $i = 0; $i < 10; $i++ ) {
if( $i == 5 ) {
continue;
}
// do more things
}
then this can trivially be rewritten as
for( $i = 0; $i < 10; $i++ ) {
if( $i != 5 ) {
// do more things
}
}
and this is now in a form which can be eval
'd:
// your code
$plugin_code = 'if( $i = 5 ) {
// do more things
}';
// framework code
for( $i = 0; $i < 10; $i++ ) {
eval($plugin_code);
}
However this still only affects the control-flow of the code you're passing into the framework. It's not possible to change the control-flow of the framework code itself.
Upvotes: 0
Reputation: 97648
Leaving aside the mechanics of eval
and continue
for a moment, I think there is a more fundamental point to make: when writing code that "plugs in" to another system, you can only do what that system allows you to do.
If the hook system simply executes the code you give it (whether via eval
, or a callback function, or any other mechanism), you cannot use it to control the flow of loops etc in the main framework code.
If the framework wanted you to do that, it would have to provide a mechanism for your plugin to signal back to the framework what you want it to do - you might register the plugin in a particular way, return a particular value from the callback, set a particular variable, etc.
If you don't want to directly modify the framework, your only option is to request such a feature from the framework's author.
Upvotes: 4
Reputation: 780673
You can't use a statement like continue
or break
in eval()
to affect an outside loop.
I suggest using a variable.
$plugin_code = 'if( $i == 5 ) {
$continue = true;
}';
$continue = false;
for( $i = 0; $i < 10; $i++ ) {
eval( $plugin_code );
if ($continue) {
continue;
}
// other code
}
If you also want to skip the rest of the plugin code, it should put that code in an else
block.
$plugin_code = 'if( $i == 5 ) {
$continue = true;
} else {
// other code
}';
IMHO, this whole thing smells fishy. The plugin is dependent on the specific variable being used for the loop, which is quite fragile.
Upvotes: 0