Tag: php extension

  • How to Make Your Own PHP Extension… Quick and Dirty

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