Overriding INI_SYSTEM and INI_PERDIR Options

In the last chapter, you used zend_alter_ini_setting() to modify some PHP INI options. Because sapi/embed thrusts your script directly into runtime mode, most of the more important INI options are unmodifiable after control has been returned to your application. To change these values, it's necessary to be able to execute code after the main engine startup so that space for these variables is available, yet before the request startup.

One approach might be to copy and paste the contents of php_embed_init() into your application, make the necessary changes in your local copy, and then use that method instead. Of course, this approach presents some problems.

First and foremost, you've effectively forked a portion of code someone else was already busily putting the work in on maintaining. Now, instead of just maintaining your application, you've got to keep up with a random bit of forked code someone else wrote as well. Fortunately, there are a few much simpler methods.

Overriding the Default php.ini File

Because embed is a sapi just like any other PHP sapi implementation, it's hooked into the engine by way of a sapi_module_struct. The embed SAPI declares and populates an instance of this structure that your application has access to even before calling php_embed_init().

In this structure is a simple char* field named php_ini_path_override. To request that embedand by extension PHP and Zenduse your alternate file, just populate this field with a NULL-terminated string prior to calling php_embed_init() as in the following modified startup_php() function in embed4.c.

static void startup_php(void)
{
 /* Create "dummy" argc/argv to hide the arguments
 * meant for our actual application */
 int argc = 1;
 char *argv[2] = { "embed4", NULL };

 php_embed_module.php_ini_path_override = "/etc/php_embed4.ini";
 php_embed_init(argc, argv PTSRMLS_CC);
}

This allows each application using the embed library to remain customizable, without imposing their configurations on each other. Conversely, if you'd rather prevent your application from using php.ini at all, simply set the php_ini_ignore field in php_embed_module and all settings will default to their built-in values unless specifically modified by your application.

Overriding Embed Startup

The sapi_module_struct also contains several callback functions, four of which are of interest for periodically taking back control during PHP startup and shutdown.

/* From main/SAPI.h */
typedef struct _sapi_module_struct {

 ...
 int (*startup)(struct _sapi_module_struct *sapi_module);
 int (*shutdown)(struct _sapi_module_struct *sapi_module);
 int (*activate)(TSRMLS_D);
 int (*deactivate)(TSRMLS_D);
 ...
} sapi_module_struct;

Do these method names ring a bell? They shouldthey correspond to an extension's MINIT, MSHUTDOWN, RINIT, and RSHUTDOWN methods and trigger during the same cycles as they do for extensions. To take advantage of these hooks, modify startup_php() in embed4 to the following version along with the additional code provided:

static int (*original_embed_startup)(struct _sapi_module_struct *sapi_module);

static int embed4_startup_callback(struct _sapi_module_struct *sapi_module)
{
 /* Call original startup callback first,
 * otherwise the environment won't be ready */
 if (original_embed_startup(sapi_module) == FAILURE) {
 /* Application failure handling may occur here */
 return FAILURE;
 }
 /* Calling the original embed_startup actually places us
 * in the ACTIVATE stage rather than the STARTUP stage, but
 * we can still alter most INI_SYSTEM and INI_PERDIR entries anyhow
 */
 zend_alter_ini_entry("max_execution_time", sizeof("max_execution_time"),
 "15", sizeof("15") - 1, PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
 zend_alter_ini_entry("safe_mode", sizeof("safe_mode"),
 "1", sizeof("1") - 1, PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
 return SUCCESS;
}

static void startup_php(void)
{
 /* Create "dummy" argc/argv to hide the arguments
 * meant for our actual application */
 int argc = 1;
 char *argv[2] = { "embed4", NULL };

 /* Override the standard startup method with our own
 * but save the original so that it can still be invoked. */
 original_embed_startup = php_embed_module.startup;
 php_embed_module.startup = embed4_startup_callback;

 php_embed_init(argc, argv PTSRMLS_CC);
}

Using options like safe_mode, open_basedir, and others will help limit what individuals scripting behavior into your application can do and should help ensure a safer, more reliable application.


The PHP Life Cycle

Variables from the Inside Out

Memory Management

Setting Up a Build Environment

Your First Extension

Returning Values

Accepting Parameters

Working with Arrays and HashTables

The Resource Data Type

PHP4 Objects

PHP5 Objects

Startup, Shutdown, and a Few Points in Between

INI Settings

Accessing Streams

Implementing Streams

Diverting the Stream

Configuration and Linking

Extension Generators

Setting Up a Host Environment

Advanced Embedding

Appendix A. A Zend API Reference

Appendix B. PHPAPI

Appendix C. Extending and Embedding Cookbook

Appendix D. Additional Resources



Extending and Embedding PHP
Extending and Embedding PHP
ISBN: 067232704X
EAN: 2147483647
Year: 2007
Pages: 175
Authors: Sara Golemon

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net