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’);”