Building PHP extensions¶
Now that you know how to compile PHP itself, we’ll move on to compiling additional extensions. We’ll discuss how the build process works and what different options are available.
Installing extensions from PECL¶
PECL, the PHP Extension Community Library, offers a large number of extensions for PHP. When extensions are removed from the main PHP distribution, they usually continue to exist in PECL. Similarly, many extensions that are now bundled with PHP were previously PECL extensions.
If you specified --with-pear
during the configuration stage of your PHP build, make install
will download
and install PECL as a part of PEAR. You will find the pecl
script in the $PREFIX/bin
directory. Installing
extensions is now as simple as running pecl install EXTNAME
, e.g.:
~/myphp> bin/pecl install apcu
This command will download, compile and install the APCu extension. The result will be a apcu.so
file in your
extension directory, which can then be loaded by passing the extension=apcu
ini option.
While pecl install
is very handy for the end-user, it is of little interest to extension developers. In the
following, we’ll describe two ways to manually build extensions: Either by importing it into the main PHP source tree
(this allows static linkage) or by doing an external build (only shared).
Adding extensions to the PHP source tree¶
There is no fundamental difference between a third-party extension and an extension bundled with PHP. As such you can build an external extension simply by copying it into the PHP source tree and then using the usual build procedure. We’ll demonstrate this using APCu as an example.
First of all, you’ll have to place the source code of the extension into the ext/EXTNAME
directory of your PHP
source tree. If the extension is available via git, this is as simple as cloning the repository from within ext/
:
~/php-src/ext> git clone https://github.com/krakjoe/apcu.git
Alternatively you can also download a source tarball and extract it:
/tmp> wget http://pecl.php.net/get/apcu-4.0.2.tgz
/tmp> tar xzf apcu-4.0.2.tgz
/tmp> mkdir ~/php-src/ext/apcu
/tmp> cp -r apcu-4.0.2/. ~/php-src/ext/apcu
The extension will contain a config.m4
file, which specifies extension-specific build instructions for use by
autoconf. To incorporate them into the ./configure
script, you’ll have to run ./buildconf
again. To ensure that
the configure file is really regenerated, it is recommended to delete it beforehand:
~/php-src> rm configure && ./buildconf
You can now use the ./config.nice
script to add APCu to your existing configuration or start over with a completely
new configure line:
~/php-src> ./config.nice --enable-apcu
# or
~/php-src> ./configure --enable-apcu # --other-options
Finally run make -jN
to perform the actual build. As we didn’t use --enable-apcu=shared
the extension is
statically linked into the PHP binary, i.e. no additional actions are needed to make use of it. Obviously you can also
use make install
to install the resulting binaries.
Building extensions using phpize
¶
It is also possible to build extensions separately from PHP by making use of the phpize
script that was already
mentioned in the Building PHP section.
phpize
plays a similar role as the ./buildconf
script used for PHP builds: First it will import the PHP build
system into your extension by copying files from $PREFIX/lib/php/build
. Among these files are php.m4
(PHP’s M4 macros), phpize.m4
(which will be renamed to configure.ac
in your extension and contains the main
build instructions) and run-tests.php
.
Then phpize
will invoke autoconf to generate a ./configure
file, which can be used to customize the extension
build. Note that it is not necessary to pass --enable-apcu
to it, as this is implicitly assumed. Instead you should
use --with-php-config
to specify the path to your php-config
script:
/tmp/apcu-4.0.2> ~/myphp/bin/phpize
Configuring for:
PHP Api Version: 20121113
Zend Module Api No: 20121113
Zend Extension Api No: 220121113
/tmp/apcu-4.0.2> ./configure --with-php-config=$HOME/myphp/bin/php-config
/tmp/apcu-4.0.2> make -jN && make install
You should always specify the --with-php-config
option when building extensions (unless you have only a single,
global installation of PHP), otherwise ./configure
will not be able to correctly determine what PHP version and
flags to build against. Specifying the php-config
script also ensures that make install
will move the generated
.so
file (which can be found in the modules/
directory) to the right extension directory.
As the run-tests.php
file was also copied during the phpize
stage, you can run the extension tests using
make test
(or an explicit call to run-tests.php
).
The make clean
target for removing compiled objects is also available and allows you to force a full rebuild of
the extension, should the incremental build fail after a change. Additionally phpize provides a cleaning option via
phpize --clean
. This will remove all the files imported by phpize
, as well as the files generated by the
./configure
script.
Displaying information about extensions¶
The PHP CLI binary provides several options to display information about extensions. You already know -m
, which will
list all loaded extensions. You can use it to verify that an extension was loaded correctly:
~/myphp/bin> ./php -dextension=apcu -m | grep apcu
apcu
There are several further switches beginning with --r
that expose Reflection functionality. For example you can use
--ri
to display the configuration of an extension:
~/myphp/bin> ./php -dextension=apcu --ri apcu
apcu
APCu Support => disabled
Version => 4.0.2
APCu Debugging => Disabled
MMAP Support => Enabled
MMAP File Mask =>
Serialization Support => broken
Revision => $Revision: 328290 $
Build Date => Jan 1 2014 16:40:00
Directive => Local Value => Master Value
apc.enabled => On => On
apc.shm_segments => 1 => 1
apc.shm_size => 32M => 32M
apc.entries_hint => 4096 => 4096
apc.gc_ttl => 3600 => 3600
apc.ttl => 0 => 0
# ...
The --re
switch lists all ini settings, constants, functions and classes added by an extension:
~/myphp/bin> ./php -dextension=apcu --re apcu
Extension [ <persistent> extension #27 apcu version 4.0.2 ] {
- INI {
Entry [ apc.enabled <SYSTEM> ]
Current = '1'
}
Entry [ apc.shm_segments <SYSTEM> ]
Current = '1'
}
# ...
}
- Constants [1] {
Constant [ boolean APCU_APC_FULL_BC ] { 1 }
}
- Functions {
Function [ <internal:apcu> function apcu_cache_info ] {
- Parameters [2] {
Parameter #0 [ <optional> $type ]
Parameter #1 [ <optional> $limited ]
}
}
# ...
}
}
The --re
switch only works for normal extensions, Zend extensions use --rz
instead. You can try this on
opcache:
~/myphp/bin> ./php -dzend_extension=opcache --rz "Zend OPcache"
Zend Extension [ Zend OPcache 7.0.3-dev Copyright (c) 1999-2013 by Zend Technologies <http://www.zend.com/> ]
As you can see, this doesn’t display any useful information. The reason is that opcache registers both a normal
extension and a Zend extension, where the former contains all ini settings, constants and functions. So in this
particular case you still need to use --re
. Other Zend extensions make their information available via --rz
though.