This is a cheat sheet on how to extend PHP. I’m learning how to fix bugs in C within the PHP source code right now using what’s google-able, the #php chat room in irc.freenode.net and “Extending and Embedding PHP” by Sara Goleman.
Preliminaries: make sure you have the right tools for building php from source. Right now these tools are:
- autoconf: 2.13
- automake: 1.4+
- libtool: 1.4.x+ (except 1.4.2)
- bison: 1.28, 1.35, 1.75, 2.0 or higher
- flex: 2.5.4 (not higher)
- re2c: 0.9.11+ (0.12.0+ for HEAD)
- Get the latest php stable version. as of this blog posting it’s php-5.2.6
- unpack the file using something like bunzip2 -c < php-5.2.6.tar.bz2 | tar xvf -
- ./configure –prefix=/usr/local –enable-debug (I’m really old school and like to put my stuff in /usr/local . YMMV.)
- make ; make install
If that worked now we’re ready to make a module. Feel free to substitute barce or BARCE in the code below with whatever you want the module name to be.
- cd ext (if you type ls you’ll see the extensions that come with php.)
- mkdir barce (I’m a narcissistic, buddhist, nihilist.)
- create a config.m4 file with this code:
PHP_ARG_ENABLE(barce,
[Whether to enable the "barce" extension],
[ --enable-barce Enable "barce" extension support])
if test $PHP_BARCE != "no"; then
PHP_SUBST(BARCE_SHARED_LIBADD)
PHP_NEW_EXTENSION(barce, barce.c, $ext_shared)
fi
- then create a php_barce.h file:
#ifndef PHP_BARCE_H /* Prevent double inclusion */ #define PHP_BARCE_H /* Define extension properties */ #define PHP_BARCE_EXTNAME "barce" #define PHP_BARCE_EXTVER "1.0" /* Import configure options * when building outside of the * PHP source tree */ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* Include PHP standard Header */ #include "php.h" /* * define the entry point symbole * Zend will use when loading this module */ extern zend_module_entry barce_module_entry; #define phpext_barce_ptr &barce_module_entry #endif /* PHP_BARCE_H */
- create a barce.c file with your functions that you are creating for PHP
#include "php_barce.h"
PHP_FUNCTION(barce_thinks_youre_cool)
{
char *name;
int name_len;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",
&name, &name_len) == FAILURE)
{
RETURN_NULL();
}
php_printf("Barce thinks you're cool, ");
PHPWRITE(name, name_len);
php_printf("!\n");
}
static function_entry php_barce_functions[] = {
PHP_FE(barce_thinks_youre_cool, NULL)
{ NULL, NULL, NULL }
};
zend_module_entry barce_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
STANDARD_MODULE_HEADER,
#endif
PHP_BARCE_EXTNAME,
php_barce_functions, /* Functions */
NULL, /* MINIT */
NULL, /* MSHUTDOWN */
NULL, /* RINIT */
NULL, /* RSHUTDOWN */
NULL, /* MINFO */
#if ZEND_MODULE_API_NO >= 20010901
PHP_BARCE_EXTVER,
#endif
STANDARD_MODULE_PROPERTIES
};
#ifdef COMPILE_DL_BARCE
ZEND_GET_MODULE(barce)
#endif
Now let’s build this puppy.
- phpize
- ./configure –enable-barce
- make
- there should now be a modules directory. copy it to /usr/local/lib/php/modules/ .
- edit php.ini and add two lines:
- extension_dir = “/usr/local/lib/php/modules”
- extension = “barce.so”
Let’s test and see if it worked:
php -r “barce_thinks_youre_cool(‘Put your name here’);”