Introduction to Creating a Basic PHP Extension
I recently decided to test my novice C skills in the field of building a PHP extension. However, despite some very good resources (here and here), there still seems to be a lack of beginner-friendly material on the subject. In this post I will be documenting a simple development environment that has worked well on a fresh CentOS 6.5 installation. Once this has been setup, we will then move on to creating a simple ‘Hello World’ extension, highlighting some of the extension platforms capabilities.
The first step we need to take is to install all the prerequisite development tools (automake, autoconf etc.) required to compile PHP from source. We can do this simply by running the following commands within a shell instance.
With these tools now successfully available to us we can now pull-down the PHP source code and checkout the desired version.
The final step is to configure and compile the code-base, specifying where you wish the installed binary files to be located. As this build is simply for testing purposes I have decided to compile as bare-bones installation as possible, whilst still taking into consideration development requirements (i.e. debugging).
Creating the Extension
With the development environment now setup we can commence with creating the extension. The extension we will be creating will provide the user with two functions, which go as follows:
- hello_world () - returns the string “Hello, World!” to the user.
- hello (string $name, [, bool $format ] ) - greets the supplied users name (i.e. “Hello, Joe!”), neatly formatting the input if specified.
So as to provide you with some context for what this extension is trying to achieve, the equivalent PHP code has been provided below.
The first file that is required to successfully compile the new extension is the ‘config.m4’ file, used when running ‘phpize’. This file defines where the extension is located and how it can be enabled.
We are then able to provide the extension with an implementation using the (‘hello.c’) example below.
Looking at the example above you will notice that there is far more boilerplate work required to initially setup and define the functions supplied. An interesting section I would like to draw your attention to is the ‘zend_parse_parameters’ function call, which supplies the function with the users provided string name and optional format boolean. If the user has decided to format the input we must first make a copy of the name value to work on. Finally, if we were required to format the string we must do some housekeeping at the end of the function, so as to not cause any memory leaks.
With the implementation now in place we are able to build and test the new extension. We must first run ‘phpize’ to create the necessary build scripts, notice that I am specifying the full path to where I installed the compiled PHP binaries. In a similar manner we must also configure the build, supplying the full path to the ‘php-config’ application.
We can now test the extension is working correctly, by running the CLI PHP binary with the new extension specified.