Problem with global variables in php extension
Posted: Wed Jul 15, 2009 10:11 am
Hello, I am trying to do a php extension for using my matlab scripts inside php scripts in Apache2.
The problem is that although I initialize the matlab_ep (which has the reference to the matlab process) when the module is loaded,
I can't use it even when for example using matlab_ejemplo (which just insert 3,14 in the workspace of Matlab).
I tried placing the variables matlab_ep inside zend globals structures making them trhead safe, but the problem remains.
The only way I can use matlab_ejemplo is calling first in the same php script matlab_ejemplp2 (which start again a new MATLAB
process and assigns it to matlab_ep). But if I call the same php script with the line matlab_ejemplo2 commented it fails and sends me back
a empty file with name of the php script.
I also tried by just using a more simple variable, a counter (named "numero" in the files). I noticed that after several seconds without calling the
function that increments it (matlab_incnum) when I finally call again this function it returns to initial value that was configured in the PHP_MINIT_FUNCTION.
Does someone has any clue of what the hell is happening.
The files I used for the extension are these:
#matlab.c#+++++++++++++++++++++++++++++++++++++++
static Engine *matlab_ep;
//static long numero;
ZEND_DECLARE_MODULE_GLOBALS(matlab)//////////////////////////
static function_entry matlab_functions[] = {
PHP_FE(matlab_ejemplo, NULL)
PHP_FE(matlab_ejemplo2, NULL)
PHP_FE(matlab_incnum,NULL)
{NULL, NULL, NULL}
};
zend_module_entry matlab_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
STANDARD_MODULE_HEADER,
#endif
PHP_MATLAB_EXTNAME,
matlab_functions,
PHP_MINIT(matlab),
PHP_MSHUTDOWN(matlab),
NULL,
NULL,
NULL,
#if ZEND_MODULE_API_NO >= 20010901
PHP_MATLAB_VERSION,
#endif
STANDARD_MODULE_PROPERTIES
};
#ifdef COMPILE_DL_MATLAB //////////
ZEND_GET_MODULE(matlab)
#endif
static void php_matlab_init_globals(zend_matlab_globals *matlab_globals)
{
/*FILE *fichero;
fichero=fopen("/tmp/carga_matlabphpext",'a');
if (!(matlab_globals->matlab_ep = engOpen("\0"))) {
fprintf(stderr, "\nCan't start MATLAB engine\n");
//fprintf(fichero, "\nCan't start MATLAB engine\n");
}*/
}
PHP_MINIT_FUNCTION(matlab)
{
putenv("HOME=/var/www"); // esto es necesario sino matlab tiene problema al inicializarse y produce un matlab_crashdump en /tmp/
if (!(matlab_ep = engOpen("\0"))){
printf(stderr,"MATLAB no se inicializado");
}
MATLAB_G(numero)=0;
ZEND_INIT_MODULE_GLOBALS(matlab, php_matlab_init_globals, NULL); //inicializar valores globales
return SUCCESS;
}
PHP_MSHUTDOWN_FUNCTION(matlab)
{
//engClose(MATLAB_G(matlab_ep));
engClose(matlab_ep);
return SUCCESS;
}
PHP_FUNCTION(matlab_ejemplo2){
//if (!(MATLAB_G(matlab_ep) = engOpen("\0"))){
if (!(matlab_ep = engOpen("\0"))){
RETURN_STRING("no se ha inicializado el matlab", 1);
}else{
RETURN_STRING("matlab inicializado", 1);
}
}
PHP_FUNCTION(matlab_ejemplo)
{
/*
* Create a variable for our data
*/
mxArray *mxR = NULL;
double *PrR = NULL;
/*
* Ejecucion
*/
//engEvalString(MATLAB_G(matlab_ep), "A=3.14;");
engEvalString(matlab_ep, "A=3.14;");
//mxR=engGetVariable(MATLAB_G(matlab_ep),"A");
mxR=engGetVariable(matlab_ep,"A");
PrR=mxGetPr(mxR);
RETURN_DOUBLE((float)(*PrR));
}
PHP_FUNCTION(matlab_incnum)
{
RETURN_LONG(MATLAB_G(numero)++);
}
#php_matlab.h#++++++++++++++++++++++++++++++
#ifndef PHP_MATLAB_H
#define PHP_MATLAB_H 1
#ifdef ZTS
#include "TSRM.h"
#endif
#include "engine.h"
ZEND_BEGIN_MODULE_GLOBALS(matlab)
//Engine *matlab_ep;
long numero;
ZEND_END_MODULE_GLOBALS(matlab)
#ifdef ZTS
#define MATLAB_G(v) TSRMG(matlab_globals_id, zend_matlab_globals *, v)
#else
#define MATLAB_G(v) (matlab_globals.v)
#endif
#define PHP_MATLAB_VERSION "1.0"
#define PHP_MATLAB_EXTNAME "MATLAB"
PHP_MINIT_FUNCTION(matlab);
PHP_MSHUTDOWN_FUNCTION(matlab);
PHP_FUNCTION(matlab_ejemplo);
PHP_FUNCTION(matlab_ejemplo2);
PHP_FUNCTION(matlab_incnum);
extern zend_module_entry matlab_module_entry;
#define phpext_MATLAB_ptr &matlab_module_entry
#endif
The problem is that although I initialize the matlab_ep (which has the reference to the matlab process) when the module is loaded,
I can't use it even when for example using matlab_ejemplo (which just insert 3,14 in the workspace of Matlab).
I tried placing the variables matlab_ep inside zend globals structures making them trhead safe, but the problem remains.
The only way I can use matlab_ejemplo is calling first in the same php script matlab_ejemplp2 (which start again a new MATLAB
process and assigns it to matlab_ep). But if I call the same php script with the line matlab_ejemplo2 commented it fails and sends me back
a empty file with name of the php script.
I also tried by just using a more simple variable, a counter (named "numero" in the files). I noticed that after several seconds without calling the
function that increments it (matlab_incnum) when I finally call again this function it returns to initial value that was configured in the PHP_MINIT_FUNCTION.
Does someone has any clue of what the hell is happening.
The files I used for the extension are these:
#matlab.c#+++++++++++++++++++++++++++++++++++++++
static Engine *matlab_ep;
//static long numero;
ZEND_DECLARE_MODULE_GLOBALS(matlab)//////////////////////////
static function_entry matlab_functions[] = {
PHP_FE(matlab_ejemplo, NULL)
PHP_FE(matlab_ejemplo2, NULL)
PHP_FE(matlab_incnum,NULL)
{NULL, NULL, NULL}
};
zend_module_entry matlab_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
STANDARD_MODULE_HEADER,
#endif
PHP_MATLAB_EXTNAME,
matlab_functions,
PHP_MINIT(matlab),
PHP_MSHUTDOWN(matlab),
NULL,
NULL,
NULL,
#if ZEND_MODULE_API_NO >= 20010901
PHP_MATLAB_VERSION,
#endif
STANDARD_MODULE_PROPERTIES
};
#ifdef COMPILE_DL_MATLAB //////////
ZEND_GET_MODULE(matlab)
#endif
static void php_matlab_init_globals(zend_matlab_globals *matlab_globals)
{
/*FILE *fichero;
fichero=fopen("/tmp/carga_matlabphpext",'a');
if (!(matlab_globals->matlab_ep = engOpen("\0"))) {
fprintf(stderr, "\nCan't start MATLAB engine\n");
//fprintf(fichero, "\nCan't start MATLAB engine\n");
}*/
}
PHP_MINIT_FUNCTION(matlab)
{
putenv("HOME=/var/www"); // esto es necesario sino matlab tiene problema al inicializarse y produce un matlab_crashdump en /tmp/
if (!(matlab_ep = engOpen("\0"))){
printf(stderr,"MATLAB no se inicializado");
}
MATLAB_G(numero)=0;
ZEND_INIT_MODULE_GLOBALS(matlab, php_matlab_init_globals, NULL); //inicializar valores globales
return SUCCESS;
}
PHP_MSHUTDOWN_FUNCTION(matlab)
{
//engClose(MATLAB_G(matlab_ep));
engClose(matlab_ep);
return SUCCESS;
}
PHP_FUNCTION(matlab_ejemplo2){
//if (!(MATLAB_G(matlab_ep) = engOpen("\0"))){
if (!(matlab_ep = engOpen("\0"))){
RETURN_STRING("no se ha inicializado el matlab", 1);
}else{
RETURN_STRING("matlab inicializado", 1);
}
}
PHP_FUNCTION(matlab_ejemplo)
{
/*
* Create a variable for our data
*/
mxArray *mxR = NULL;
double *PrR = NULL;
/*
* Ejecucion
*/
//engEvalString(MATLAB_G(matlab_ep), "A=3.14;");
engEvalString(matlab_ep, "A=3.14;");
//mxR=engGetVariable(MATLAB_G(matlab_ep),"A");
mxR=engGetVariable(matlab_ep,"A");
PrR=mxGetPr(mxR);
RETURN_DOUBLE((float)(*PrR));
}
PHP_FUNCTION(matlab_incnum)
{
RETURN_LONG(MATLAB_G(numero)++);
}
#php_matlab.h#++++++++++++++++++++++++++++++
#ifndef PHP_MATLAB_H
#define PHP_MATLAB_H 1
#ifdef ZTS
#include "TSRM.h"
#endif
#include "engine.h"
ZEND_BEGIN_MODULE_GLOBALS(matlab)
//Engine *matlab_ep;
long numero;
ZEND_END_MODULE_GLOBALS(matlab)
#ifdef ZTS
#define MATLAB_G(v) TSRMG(matlab_globals_id, zend_matlab_globals *, v)
#else
#define MATLAB_G(v) (matlab_globals.v)
#endif
#define PHP_MATLAB_VERSION "1.0"
#define PHP_MATLAB_EXTNAME "MATLAB"
PHP_MINIT_FUNCTION(matlab);
PHP_MSHUTDOWN_FUNCTION(matlab);
PHP_FUNCTION(matlab_ejemplo);
PHP_FUNCTION(matlab_ejemplo2);
PHP_FUNCTION(matlab_incnum);
extern zend_module_entry matlab_module_entry;
#define phpext_MATLAB_ptr &matlab_module_entry
#endif