Skip to content
moriyoshi edited this page Sep 12, 2010 · 31 revisions

Boost.PHP Basics

A typical Boost.PHP extension consists of the following source files:

  • The main C++ source file.
  • Optional source files.

Since the magic has to happen within a single compilation unit, everything related to the extension itself must go to the main source file. Other thingie can be in different units.

The main C++ source file consists of the following portions:

  • The module class definition.
  • Bootstrap macros.

An example of an empty module is shown below:

#include "boost/php/module.hpp"

using namespace boost;

// (1) Module class definition
class my_first_module
    : public php::module {
public:
    // Handler class
    class handler
        : public php::module::handler {
    public:
        handler(my_first_module* mod)
            :php::module::handler(mod) {}
    };
public:
    my_first_module(zend_module_entry* entry)
        : php::module(entry) {
    }
};

// (2) Bootstrap macros
#define BOOST_PHP_MODULE_NAME m001
#define BOOST_PHP_MODULE_CAPITALIZED_NAME M001
#define BOOST_PHP_MODULE_VERSION "0.1"
#define BOOST_PHP_MODULE_CLASS_NAME my_first_module

#include "boost/php/module_def.hpp"

Every Boost.PHP-powered extension must contain a module class. A module class is a singleton which gets initialized right after the module is loaded. You can modify the contents of zend_module_entry within the module class’s constructor.

The module class must contain a typedef or an inner class definition for a handler. A handler is a class that has 4 methods that handles the lifecycle callbacks from the PHP runtime

  • handler::__initialize() – called when the module is being initialized
  • handler::__activate() – called when the runtime is about to handle a new request
  • handler::__deactivate() – called when the runtime is completing the request
  • handler::__finalize() – called when the module is being cleaned up

The handler and the empty definitions of those methods are defined as boost::php::module::handle, so you don’t bother to write them if the module class is derived from it.

Bootstrap macros are necessary to define several functions and global variables required by PHP. There are only 4 macros that need to be defined:

  • BOOST_PHP_MODULE_NAME – the name of the extension
  • BOOST_PHP_MODULE_CAPITALIZED_NAME – the all-capitalized name of the extension
  • BOOST_PHP_MODULE_VERSION – the version of the extension as a string literal
  • BOOST_PHP_MODULE_CLASS_NAME – the name of the module class

And finally, you have to include

#include "boost/php/module_def.hpp"</pre> to do the trick.

Adding Functions

To add functions in the empty module shown above, You need to the following steps:

  1. Include <boost/php/function.hpp>
  2. Make the module class derive from boost::php::function_container with T being the module class so that the members of the superclass will be “mixed in”.
  3. Add plain C++ functions you want to expose to PHP in the handler class.
  4. Create function entries by defun() methods giving each the function name and the pointer to the corresponding C++ function defined in the handler class, within the constructor of the module class.
  5. Setting functions member of the module entry to the function entries built above.

The following example exposes add() function which calculates the sum of the two arguments:

#include "boost/php/module.hpp"
#include "boost/php/function.hpp"

using namespace boost;

class my_first_module
    : public php::module,
      public php::function_container<my_first_module> {
public:
    class handler
        : public php::module::handler {
    public:
        handler(my_first_module* mod)
            :php::module::handler(mod) {}

        int add(int a, int b) {
            return a + b;
        }
    };
public:
    my_first_module(zend_module_entry* entry)
        : php::module(entry) {
        entry->functions = defun("add", &handler::add).
    }
};

#define BOOST_PHP_MODULE_NAME m002
#define BOOST_PHP_MODULE_CAPITALIZED_NAME M002
#define BOOST_PHP_MODULE_VERSION "0.1"
#define BOOST_PHP_MODULE_CLASS_NAME my_first_module

#include "boost/php/module_def.hpp"

Typecasts are done automatically according to the PHP’s type-juggling rule. For example,

<?php
var_dump(add(1, 2));
var_dump(add(1, "2"));
var_dump(add("1", "2"));
var_dump(add("1", "2"));
?>

All of these invocations of the extension functihon result in 3.

The following types are allowed for the function arguments:

  • Numeric types: int / long / double
  • Strings: std::string
  • Resources: boost::php::resource_handle
  • Arrays: boost::php::array
  • Variant values: boost::php::value_ptr
  • Objects: (a reference to a Boost.PHP object)
Clone this wiki locally