Building Your First Extension

Now that you've got all the files in place, it's time to make it go. As with building the main PHP binary, there are different steps to be taken depending on whether you're compiling for *nix or for Windows.

Building Under *nix

The first step is to generate a ./configure script using the information in config.m4 as a template. This can be done by running the phpize program installed when you compiled the main PHP binary.

$ phpize PHP Api Version: 20041225 Zend Module Api No: 20050617 Zend Extension Api No: 220050617

Note

The extra 2 at the start of Zend Extension Api No isn't a typo; it corresponds to the Zend Engine 2 version and is meant to keep this API number greater than its ZE1 counterpart.

If you look in the current directory at this point, you'll notice a lot more files than you had there a moment ago. The phpize program combined the information in your extension's config.m4 file with data collected from your PHP build and laid out all the pieces necessary to make a compile happen. This means that you don't have to struggle with makefiles and locating the PHP headers you'll be compiling against. PHP has already done that job for you.

The next step is a simple ./configure that you might perform with any other OSS package. You're not configuring the entire PHP bundle here, just your one extension, so all you need to type in is the following:

$ ./configure enable-sample

Notice that not even enable-debug and enable-maintainer-zts were used here. That's because phpize has already taken those values from the main PHP build and applied them to your extension's ./configure script.

Now build it! Like any other package, you can just type make and the generated script files will handle the rest.

When the build process finishes, you'll be treated to a message stating that sample.so has been compiled and placed in a directory called "modules" within your current build directory.

Building Under Windows

The config.m4 file you created earlier was actually specific to the *nix build. In order to make your extension compile under Windows, you'll need to create a separatebut similarconfiguration file for it.

Add config.w32 with the following contents to your ext/sample directory:

ARG_ENABLE("sample", "enable sample extension", "no"); if (PHP_SAMPLE != "no") { EXTENSION("sample", "sample.c"); }

As you can see, this file bears a resemblance on a high level to config.m4. The option is declared, tested, and conditionally used to enable the build of your extension.

Now you'll repeat a few of the steps you performed in Chapter 4, "Setting Up a Build Environment," when you built the PHP core. Start by opening up a build window from the Start menu by selecting All Programs, Microsoft Platform SDK for Windows Server 2003 SP1, Open Build Environment Window, Windows 2000 Build Environment, Set Windows 2000 Build Environment (Debug), and running the C:Program FilesMicrosoft Visual Studio 8VCinvcvars32.bat batch file.

Remember, your installation might require you to select a different build target or run a slightly different batch file. Refer to the notes in the corresponding section of Chapter 4 to refresh your memory.

Again, you'll want to go to the root of your build directory and rebuild the configure script.

C:Program FilesMicrosoft Platform SDK> cd PHPDEVphp-5.1.0 C:PHPDEVphp-5.1.0> buildconf.bat Rebuilding configure.js Now run 'cscript /nologo configure.js help'

This time, you'll run the configure script with an abridged set of options. Because you'll be focusing on just your extension and not the whole of PHP, you can leave out options pertaining to other extensions; however, unlike the Unix build, you do need to include the enable-debug switch explicitly even though the core build already has it.

The only crucial switch you'll need hereapart from debug of courseis enable-sample=shared. The shared option is required here because configure.js doesn't know that you're planning to build sample as a loadable extension. Your configure line should therefore look something like this:

C:PHPDEVphp-5.1.0> cscript /nologo configure.js enable-debug enable-sample=shared

Note

Recall that enable-maintainer-zts is not required here as all Win32 builds assume that ZTS must be enabled. Options relating to SAPIssuch as embedare also not required here as the SAPI layer is independent from the extension layer.

Lastly, you're ready to build the extension. Because this build is based from the coreunlike the Unix extension build, which was based from the extensionyou'll need to specify the target name in your build line.

C:PHPDEVphp-5.1.0> nmake php_sample.dll

Once compilation is complete, you should have a working php_sample.dll binary ready to be used in the next step. Remember, because this book focuses on *nix development, the extension will be referred to as sample.so rather than php_sample.dll in all following text.

Loading an Extension Built as a Shared Module

In order for PHP to locate this module when requested, it needs to be located in the same directory as specified in your php.ini setting: extension_dir. By default, php.ini is located in /usr/local/lib/php.ini; however, this default can be changed and often is with distribution packaging systems. Check the output of php -i to see where PHP is looking for your config file.

This setting, in an unmodified php.ini, is an unhelpful ./. If you don't already have extensions being loaded, or just don't have any extensions other than sample.so anyway, you can change this value to the location where make put your module. Otherwise, just copy sample.so to the directory where this setting is pointing.

After extension_dir is pointing to the right place, there are two ways to tell PHP to load your module. The first is using the dl() function within your script:

If this script doesn't show sample as a loaded module, something has gone wrong. Look for error messages above the output for a clue, or refer to your error_log if one is defined in your php.ini.

The second, and much more common, method is to specify the module in your php.ini using the extension directive. The extension setting is relatively unique among php.ini settings in that it can be specified multiple times with different values. So if you already have an extension setting in your php.ini, don't add it to the same line like a delimited list; instead insert an additional line containing just sample.so. At this point your php.ini should look something like this:

extension_dir=/usr/local/lib/php/modules/ extension=sample.so

Now you could run the same script without the dl() line, or just issue the command php -m and still see "sample" in the list of loaded modules.

Note

All sample code in this and the following chapters will assume you've loaded the current extension using this method. If you plan on using dl() instead, be sure to add the appropriate load line to the sample scripts.

Категории