Hi All,
I'm just new to php embed application but I'm at good point
after some work/fighting with the engine API. My intention is
to run different php scripts in a multithreaded application at the
same time. Furthermore I don't need to make some php
intercomunications and/or parallel script exection. So, the approch
I follow, for embedding the PHP in to my application, is the usual
(I guess ;-) sapi with some other hints from the plpgsql, PHP-Interpreter
source codes. So I initialize the php engine with:
int initEngine( void )
{
zend_compiler_globals *compiler_globals;
zend_executor_globals *executor_globals;
php_core_globals *core_globals;
sapi_globals_struct *sapi_globals;
void ***tsrm_ls;
if ( ze_started == true )
{
return 0;
}
if ( !tsrm_startup( 128, 32, TSRM_ERROR_LEVEL_CORE, "/tmp/TSRM.log") )
{
ANY_LOG( 0, "Unable to init the PHP TSRM!", ANY_LOG_FATAL );
return -1;
}
/* get some globals from the PHP engine */
compiler_globals = ts_resource( compiler_globals_id );
executor_globals = ts_resource( executor_globals_id );
core_globals = ts_resource( core_globals_id );
sapi_globals = ts_resource( sapi_globals_id );
tsrm_ls = ts_resource( 0 );
HSI_sapi.php_ini_path_override = "/etc/php.ini";
sapi_startup( &HSI_sapi );
ze_started = true;
if ( php_module_startup( &HSI_sapi, NULL, 0 ) == FAILURE )
{
ANY_LOG( 0, "Failed to initialize PHP", ANY_LOG_FATAL );
return -1;
}
}
while each context is allocated by the follow:
void *createInterpreter( void )
{
void *interp = NULL;
void *prev_interp = NULL;
interp = tsrm_new_interpreter_context();
prev_interp = tsrm_set_interpreter_context( interp );
{
TSRMLS_FETCH();
zend_alter_ini_entry("register_argc_argv", 19, "0", 1, PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
zend_alter_ini_entry("html_errors", 12, "0", 1, PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
zend_alter_ini_entry("implicit_flush", 15, "1", 1, PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
zend_alter_ini_entry("max_execution_time", 19, "0", 1, PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
SG( headers_sent ) = 1;
SG( request_info ).no_headers = 1;
SG( options ) = SAPI_OPTION_NO_CHDIR;
php_request_startup( TSRMLS_C );
PG( during_request_startup ) = 0;
tsrm_set_interpreter_context( prev_interp );
}
return( interp );
}
my scripts are evalutated with:
bool phpEval( void *interp, char *cmd, zval *zv )
{
bool retVal = true;
void *prev_interp = NULL;
prev_interp = tsrm_set_interpreter_context( interp );
{
TSRMLS_FETCH();
zend_try
{
if ( zend_eval_string( cmd, zv, "PHP Embedded Interface" TSRMLS_CC ) == FAILURE )
{
fprintf( stderr, "Unable to send the command '%s' on Php", cmd );
retVal = false;
goto out;
}
}
zend_catch
{
fprintf( stderr, "Unable to send the command '%s' on Php", cmd );
retVal = false;
goto out;
}
zend_end_try()
{
}
}
out:
tsrm_set_interpreter_context( prev_interp );
return( retVal );
}
so now the question is, since I execute each php script in a different context
how can I get global variables from it? I tried to use the code below but it doesn't
work. Obviously the zend_hash_find( &EG(symbol_table) ... ) works great in a
"standard" application using the macros PHP_EMBED_START/END_BLOCK(argc,argv):
zval **data = NULL;
HashTable *arrayHash = NULL;
void *prev_interp = NULL;
prev_interp = tsrm_set_interpreter_context( self->interp );
{
TSRMLS_FETCH();
if ( zend_hash_find( &EG(symbol_table), "myVar", sizeof( "myVar" ), (void **)&data) == FAILURE )
{
fprintf( stderr, "The infoString array myVar not found in $GLOBALS" );
goto out;
}
if ( data == `NULL` )
{
fprintf( stderr, "myVar doesn't contains any data" );
goto out;
}
}
out:
tsrm_set_interpreter_context( prev_interp );
I guess that the EG(symbol_table) isn't correct here but I don't find any place
where to clarify how to get global variables from a given context. Does anyone can
explain me how to do it?
Thanks in advance.
Roberto Fichera.
At 10.25 05/01/2007, you wrote:
Hi All,
I'm just new to php embed application but I'm at good point
after some work/fighting with the engine API. My intention is
to run different php scripts in a multithreaded application at the
same time. Furthermore I don't need to make some php
intercomunications and/or parallel script exection. So, the approch
I follow, for embedding the PHP in to my application, is the usual
(I guess ;-) sapi with some other hints from the plpgsql, PHP-Interpreter
source codes. So I initialize the php engine with:int initEngine( void )
{
zend_compiler_globals *compiler_globals;
zend_executor_globals *executor_globals;
php_core_globals *core_globals;
sapi_globals_struct *sapi_globals;
void ***tsrm_ls;if ( ze_started == true )
{
return 0;
}if ( !tsrm_startup( 128, 32, TSRM_ERROR_LEVEL_CORE, "/tmp/TSRM.log") )
{
ANY_LOG( 0, "Unable to init the PHP TSRM!", ANY_LOG_FATAL );
return -1;
}/* get some globals from the PHP engine */
compiler_globals = ts_resource( compiler_globals_id );
executor_globals = ts_resource( executor_globals_id );
core_globals = ts_resource( core_globals_id );
sapi_globals = ts_resource( sapi_globals_id );
tsrm_ls = ts_resource( 0 );HSI_sapi.php_ini_path_override = "/etc/php.ini";
sapi_startup( &HSI_sapi );
ze_started = true;
if ( php_module_startup( &HSI_sapi, NULL, 0 ) == FAILURE )
{
ANY_LOG( 0, "Failed to initialize PHP", ANY_LOG_FATAL );
return -1;
}
}while each context is allocated by the follow:
void *createInterpreter( void )
{
void *interp = NULL;
void *prev_interp = NULL;interp = tsrm_new_interpreter_context();
prev_interp = tsrm_set_interpreter_context( interp );
{
TSRMLS_FETCH();zend_alter_ini_entry("register_argc_argv", 19, "0", 1,
PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
zend_alter_ini_entry("html_errors", 12, "0", 1, PHP_INI_SYSTEM,
PHP_INI_STAGE_ACTIVATE);
zend_alter_ini_entry("implicit_flush", 15, "1", 1, PHP_INI_SYSTEM,
PHP_INI_STAGE_ACTIVATE);
zend_alter_ini_entry("max_execution_time", 19, "0", 1,
PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);SG( headers_sent ) = 1;
SG( request_info ).no_headers = 1;
SG( options ) = SAPI_OPTION_NO_CHDIR;php_request_startup( TSRMLS_C );
PG( during_request_startup ) = 0;
tsrm_set_interpreter_context( prev_interp );
}return( interp );
}my scripts are evalutated with:
bool phpEval( void *interp, char *cmd, zval *zv )
{
bool retVal = true;
void *prev_interp = NULL;prev_interp = tsrm_set_interpreter_context( interp );
{
TSRMLS_FETCH();zend_try
{
if ( zend_eval_string( cmd, zv, "PHP Embedded Interface"
TSRMLS_CC ) == FAILURE )
{
fprintf( stderr, "Unable to send the command '%s' on Php", cmd );
retVal = false;
goto out;
}
}
zend_catch
{
fprintf( stderr, "Unable to send the command '%s' on Php", cmd );
retVal = false;
goto out;
}
zend_end_try()
{
}
}out:
tsrm_set_interpreter_context( prev_interp );return( retVal );
}so now the question is, since I execute each php script in a different context
how can I get global variables from it? I tried to use the code below
but it doesn't
work. Obviously the zend_hash_find( &EG(symbol_table) ... ) works great in a
"standard" application using the macros PHP_EMBED_START/END_BLOCK(argc,argv):zval **data = NULL;
HashTable *arrayHash = NULL;
void *prev_interp = NULL;prev_interp = tsrm_set_interpreter_context( self->interp );
{
TSRMLS_FETCH();if ( zend_hash_find( &EG(symbol_table), "myVar", sizeof( "myVar"
), (void **)&data) == FAILURE )
{
fprintf( stderr, "The infoString array myVar not found in $GLOBALS" );
goto out;
}if ( data ==
NULL
)
{
fprintf( stderr, "myVar doesn't contains any data" );
goto out;
}
}out:
tsrm_set_interpreter_context( prev_interp );I guess that the EG(symbol_table) isn't correct here but I don't find
any place
where to clarify how to get global variables from a given context.
Does anyone can
explain me how to do it?
I found the solution myself :-))!! Basically using the active_symbol_table instead of
the symbol_table and adding +1 to the sizeof()
, I solved the problem :-))!!!
zval **data = NULL;
HashTable *arrayHash = NULL;
void *prev_interp = NULL;
prev_interp = tsrm_set_interpreter_context( self->interp );
{
TSRMLS_FETCH();
if ( zend_hash_find( EG(active_symbol_table), "myVar", sizeof( "myVar" )+1, (void **)&data) == FAILURE )
{
fprintf( stderr, "The infoString array myVar not found in $GLOBALS" );
goto out;
}
if ( data == `NULL` )
{
fprintf( stderr, "myVar doesn't contains any data" );
goto out;
}
}
out:
tsrm_set_interpreter_context( prev_interp );
Now my problem is how to find declared functions in a context. Which hash table
I have to use?
Thanks in advance.
Roberto Fichera.
--
Roberto Fichera.
Hi Roberto,
Now my problem is how to find declared functions in a context. Which hash table
I have to use?
Just take a look at the structure behind the executor_globals EG struct:
http://lxr.php.net/source/ZendEngine2/zend_globals.h#147 to see which
HashTable might contain the function_table. In that structure you might
find other useful elements )(maybe you need the class table or constants
table, too?) ;-)
johannes