Dealing with Errors
When a serious error occurs, such as a script parse error, PHP will go into bailout mode. In the case of the simple embed examples you've seen so far, that means jumping directly to the PHP_EMBED_END_BLOCK() macro and bypassing any remaining code within the block. Because the purpose of most applications that embed the PHP interpreter is not strictly about executing PHP code, it makes sense to avoid having a PHP script bailout kill the entire application.
One approach might be to confine all executions to very small START/END blocks, so that a given bailout only bails out on the current chuck. The disadvantage to this is that each START/END block functions as its own isolated PHP request. Thus a pair of START/END blocks, as shown here, will not share a common scope, even though the legal syntax of each should allow one block to work with the other:
int main(int argc, char *argv[]) { PHP_EMBED_START_BLOCK(argc, argv) zend_eval_string("$a = 1;", NULL, "Script Block 1"); PHP_EMBED_END_BLOCK() PHP_EMBED_START_BLOCK(argc, argv) /* Will display "NULL", * since variable $a isn't defined in this request */ zend_eval_string("var_dump($a);", NULL, "Script Block 2"); PHP_EMBED_END_BLOCK() return 0; }
Another way to isolate these two zend_eval_string() calls is through the use of some Zend-specific pseudolanguage constructs: zend_try, zend_catch, and zend_end_try. Using these constructs, your application can set up a temporary override for the bailout target and deal with these serious errors in a sane manner. Consider the following variation of the prior example:
int main(int argc, char *argv[]) { PHP_EMBED_START_BLOCK(argc, argv) zend_try { /* Try to execute something that will fail */ zend_eval_string("$1a = 1;", NULL, "Script Block 1a"); } zend_catch { /* There was an error! * Try a different line instead */ zend_eval_string("$a = 1;", NULL, "Script Block 1"); } zend_end_try(); /* Will display "NULL", * since variable $a isn't defined in this request */ zend_eval_string("var_dump($a);", NULL, "Script Block 2"); PHP_EMBED_END_BLOCK() return 0; }
In the second version of this code sample, the parse error that occurs within the zend_try block only bails out as far as the zend_catch block where it's handled by using a good piece of code instead. The same block could be applied to the var_dump() section later on as well; go ahead and try that out for yourself.
Initializing PHP
|