By now, you must have noticed the use of macros here and there starting with
TSRM, which stands for Thread-Safe Resource Manager. These macros give
your extension the possibility of having its own global variables, as previously
mentioned.
When writing a PHP extension, whether in a multi-process or a multi-
threaded environment, you access your extension’s global variables via this
mechanism. If you want to use global variable accessor macros (such as the
MYFILE_G() macro), you need to make sure that the TSRM context information
is present in your current function. For performance reasons, the Zend Engine
tries to pass around this context as a parameter as much as possible, including
to your PHP_FUNCTION() definition. For this reason, when writing code that uses
the accessor macro (such as MYFILE_G()) in the scope of PHP_FUNCTION(), you don’t have to make any special declarations. However, if your PHP function
calls other C functions that need access to the global variables, you must
either pass that context to the C function as an extra parameter or you must
fetch the context that is slower.
To fetch the context, you can just use the TSRMLS_FETCH() at the beginning
of a code block in which you need access to the global variables. For example:
void myfunc()
{
TSRMLS_FETCH();
MYFILE_G(myglobal) = 2;
}
If you want your code to be more optimized, it is better to pass the con-
text to your function directly (as mentioned before, it is automatically avail-
able to you in PHP_FUNCTION()’s scope). You can do this by using the TSRMLS_C (C
for call) and TSRMLS_CC (CC for call and comma) macros. The former should be
used when the context is the only parameter, and the latter when it is part of a
function that accepts more than one argument. In the latter’s case, it may not
be the first argument because it places a comma before the context, hence its
name.
In the function’s prototype, you will respectively use the TSRMLS_D and
TSRMLS_DC macros to declare that you’re receiving the context.
Here’s the previous example re-written to take advantage of passing the
context by parameter:
void myfunc(TSRMLS_D)
{
MYFILE_G(myglobal) = 2;
}
PHP_FUNCTION(my_php_function)
{
…
myfunc(TSRMLS_C);
…
}
SUMMARY
So far, you learned enough about writing PHP extensions to create your own
custom extensions. This chapter covered the important fundamentals to
writing and understanding PHP extensions. The extension API framework provided by the Zend Engine is extremely rich and allows you to write object-
oriented extensions. For many of the advanced features, very little documenta-
tion currently exists. Of course, nothing replaces looking at the core PHP
extensions bundled with PHP. You can learn a lot from skimming through
existing source code, and the fundamentals you have learned in this chapter
should allow you to do so.
Additional information can be found in the extending PHP chapter of the
PHP manual at http://www.php.net/manual/en/zend.php Also, you might
want to consider joining the PHP developers mailing list, mailto:inter-
nals@lists.php.net, which deals with developing PHP itself. In addition, you
should look at a new extension-generating tool called PECL_Gen ( http://pear.php.net/package/PECL_Gen ), which is under development and will have
more features than the ext_skel script used in this chapter.
