These macros look something like this for a thread-safe build:
#define TSRMLS_FETCH( ) void ***tsrm_ls = (void ***) ts_resource_ex(0, NULL)
#define TSRMG(id,type,el) (((type) (*((void ***) \
tsrm_ls))[TSRM_UNSHUFFLE_RSRC_ID(id)])->el)
#define TSRMLS_D void ***tsrm_ls
#define TSRMLS_DC , TSRMLS_D
#define TSRMLS_C tsrm_ls
#define TSRMLS_CC , TSRMLS_C
For the non-thread-safe build, they don't do
anything and are simply defined as:
#define TSRMLS_FETCH( )
#define TSRMLS_D void
#define TSRMLS_DC
#define TSRMLS_C
#define TSRMLS_CC
#endif /* ZTS */
So, to create extensionwide global variables, you first need to
create a struct in which to store them, along with the thread-safe
and non-thread-safe access macros.
The struct looks like this in the php_ foo.h
header file:
ZEND_BEGIN_MODULE_GLOBALS(foo)
int some_integer;
char *some_string;
ZEND_END_MODULE_GLOBALS(foo)
#ifdef ZTS
# define FOO_G(v) TSRMG(foo_globals_id, zend_foo_globals *, v)
#else
# define FOO_G(v) (foo_globals.v)
#endif
The ext_skel tool creates most of this for you.
You simply have to uncomment the right sections.
In the main extension file, foo.c, you need to
declare that your extension has globals and define a function to
initialize each member of your global struct:
ZEND_DECLARE_MODULE_GLOBALS(foo)
static void php_foo_init_globals(zend_foo_globals *foo_globals)
{
foo_globals->some_integer = 0;
foo_globals->some_string = NULL;
}
To have your initialization function called on module initialization,
add this inside the PHP_MINIT_FUNCTION( ):
ZEND_INIT_MODULE_GLOBALS(foo, php_foo_init_globals, NULL);
To access one of these globals, some_integer or
some_string, use
FOO_G(some_integer) or
FOO_G(some_string). Note that the struct must be
available in the function in order to use the FOO_G(
) macro. For all standard PHP functions, the global struct
is automatically and invisibly passed in.
However, if you write your own utility functions that need to access
the global values, you'll have to pass in the struct
yourself. The TSRMLS_CC macro does this for you,
so calls to your utility functions look like:
foo_utility_function(my_arg TSRMLS_CC);