PHP ini file user_agent configuration option

Today I discovered the user_agent php.ini configuration option. Basically it allows you to specify the user agent PHP uses when it sends HTTP requests for files. I was screen scraping some data from Wikipedia (processing URI schemes) and it was replying with a 403 error, presumably because they’ve banned the default PHP user agent. Anyway I just changed my user agent to a copy of my one from Firefox and things started working. Pretty handy option!

File upload error – unable to create a temporary file in Unknown on line 0

I was working with phpMyAdmin and I got the following error:

 File upload error - unable to create a temporary file in Unknown on line 0

The problem was that the upload_tmp_dir setting in my php.ini file was specified twice. Once up the top of the file where I was editing it, and then later in the file where I didn’t see it. So the setting I wanted wasn’t being applied. If you get this error double check you’ve only got one setting for upload_tmp_dir.

Profiling a PHP script

Note: if you’re a web developer you might be interested in registering to become a ProgClub member. ProgClub is a free international club for computer programmers and we run some mailing lists you might like to hang out on to chat about software development, life, etc.

Warning: this article is long and detailed and contains a fair number of notes about experimental modifications. If you’re going to try applying the ideas in this file I strong encourage you to read the whole article first, and especially the comments which include important notes about how to patch the software properly (rather than just commenting stuff out which I do initially). You have been warned!

Update: this article is over three years old. It’s helped a number of people, which is nice, but it’s time to move on. The APD component is ancient and unmaintained. If you want a PHP profiler I strongly recommend Xdebug. Seriously: use Xdebug. Oh, and be careful!

Let me take you on a fabulous adventure.

I was working on a new web app I’m doing and the app felt a little sluggish. I wanted to know what was causing the sluggishness. Was it database access? Encryption? Compression? Something else?

So I did a search for profiling a php script and turned up this article (Simplest way to profile a PHP script) at StackOverflow. I read this answer which suggested the PECL APD extension so I figured I’d check it out.

I found the documentation for APD (APD stands for Advanced PHP Debugger) and I read the installation instructions, but there didn’t seem to be anything there. Admittedly I was just looking for the Ubuntu package to install with apt-get. Now that I’m writing this up I realise I should have read Installation of PECL extensions first, but I missed that at the time.

I started throwing commands at my terminal:

 # apt-cache search apd
 # apt-cache search apd php
 # apt-cache search apd | grep php
 # apt-cache search apd | grep PHP
 # cd /usr
 # find -name "apd.so"
 # apt-cache search pecl
 # apt-get install dh-make-php

The dh-make-php package was the closest thing I could find, so I thought maybe I would try that. It said “dh-make-php – Creates Debian source packages for PHP PEAR and PECL extensions”, sounded pretty close. Maybe. Anyway, before I confirmed the installation of of dh-make-php I thought I’d do some more research.

I searched for installing pecl apd ubuntu but that didn’t seem to turn up much. The first result was in French, and it only seemed to be an unanswered question about an error during compilation.

I searched for apd.so ubuntu (because the installation instructions that I read said I needed apd.so) and I turned up How to install apd in debian php5 at ServerFault. The answer said to install php-pear and then run “pecl install apd”. So I did “apt-get install php-pear” and that worked well enough. Then I ran pecl:

root@sixsigma:~# pecl install apd
downloading apd-1.0.1.tgz ...
Starting to download apd-1.0.1.tgz (36,643 bytes)
..........done: 36,643 bytes
15 source files, building
running: phpize
sh: phpize: not found
ERROR: `phpize' failed

I searched for sh: phpize: not found ERROR: `phpize’ failed and found phpize: command not found which said I needed to apt-get install php5-dev, which I did. Then I tried again:

root@sixsigma:~# pecl install apd
downloading apd-1.0.1.tgz ...
Starting to download apd-1.0.1.tgz (36,643 bytes)
..........done: 36,643 bytes
15 source files, building
running: phpize
Cannot find config.m4.
Make sure that you run '/usr/bin/phpize' in the top level source directory of the module

ERROR: `phpize' failed

I searched for the error message running: phpize Cannot find config.m4. and found Cannot find config.m4 + phpize +Resolved which just said like the error message said that I needed to run from the top level source directory. Whatever that was supposed to mean.

I searched for the downloaded file apd-1.0.1.tgz and found it in /build/buildd/php5-5.3.2/pear-build-download/. So I tried the following:

root@sixsigma:~# cd /build/buildd/php5-5.3.2/pear-build-download/
root@sixsigma:/build/buildd/php5-5.3.2/pear-build-download# tar xvf apd-1.0.1.tgz
package.xml
apd-1.0.1/LICENSE
apd-1.0.1/Makefile.in
apd-1.0.1/README
apd-1.0.1/apd.dsp
apd-1.0.1/apd_array.c
apd-1.0.1/apd_array.h
apd-1.0.1/apd_lib.c
apd-1.0.1/apd_lib.h
apd-1.0.1/apd_summary.c
apd-1.0.1/build
apd-1.0.1/build/CVS
apd-1.0.1/build/CVS/Entries
apd-1.0.1/build/CVS/Repository
apd-1.0.1/build/CVS/Root
apd-1.0.1/build/mkdep.awk
apd-1.0.1/build/scan_makefile_in.awk
apd-1.0.1/build/shtool
apd-1.0.1/config.m4
apd-1.0.1/php_apd.c
apd-1.0.1/php_apd.h
apd-1.0.1/php_sockets.h
apd-1.0.1/php_sockets_win.h
apd-1.0.1/pprofp
apd-1.0.1/pprof2calltree
apd-1.0.1/win32compat.c
apd-1.0.1/win32compat.h
root@sixsigma:/build/buildd/php5-5.3.2/pear-build-download# cd apd-1.0.1
root@sixsigma:/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1# ls
apd_array.c  apd_lib.h      LICENSE      php_sockets.h      README
apd_array.h  apd_summary.c  Makefile.in  php_sockets_win.h  win32compat.c
apd.dsp      build          php_apd.c    pprof2calltree     win32compat.h
apd_lib.c    config.m4      php_apd.h    pprofp

It wasn’t clear what to do next. There was no configure script or Makefile in the directory.

I searched for the full error message Starting to download apd-1.0.1.tgz (36,643 bytes) ……….done: 36,643 bytes 15 source files, building running: phpize Cannot find config.m4. and found this which seemed to suggest I needed to run “pear channel-update pear.php.net” which I did, but nothing exciting happened:

root@sixsigma:/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1# pear channel-update pear.php.net
Updating channel "pear.php.net"
Channel "pear.php.net" is up to date
root@sixsigma:/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1# pecl install apd
downloading apd-1.0.1.tgz ...
Starting to download apd-1.0.1.tgz (36,643 bytes)
..........done: 36,643 bytes
15 source files, building
running: phpize
Cannot find config.m4.
Make sure that you run '/usr/bin/phpize' in the top level source directory of the module

ERROR: `phpize' failed

The error message had said something about “phpize” so I figured I’d give that a go.

root@sixsigma:/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1# phpize
Configuring for:
PHP Api Version:         20090626
Zend Module Api No:      20090626
Zend Extension Api No:   220090626
root@sixsigma:/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1# ls
acinclude.m4  apd_summary.c   configure        missing            pprofp
aclocal.m4    autom4te.cache  configure.in     mkinstalldirs      README
apd_array.c   build           install-sh       php_apd.c          run-tests.php
apd_array.h   config.guess    LICENSE          php_apd.h          win32compat.c
apd.dsp       config.h.in     ltmain.sh        php_sockets.h      win32compat.h
apd_lib.c     config.m4       Makefile.global  php_sockets_win.h
apd_lib.h     config.sub      Makefile.in      pprof2calltree

And there you go! The “phpize” command built me a configure script. So…

root@sixsigma:/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1# ./configure
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for a sed that does not truncate output... /bin/sed
checking for cc... cc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether cc accepts -g... yes
checking for cc option to accept ISO C89... none needed
checking how to run the C preprocessor... cc -E
checking for icc... no
checking for suncc... no
checking whether cc understands -c and -o together... yes
checking for system library directory... lib
checking if compiler supports -R... no
checking if compiler supports -Wl,-rpath,... yes
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking target system type... x86_64-unknown-linux-gnu
checking for PHP prefix... /usr
checking for PHP includes... -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/TSRM -I/usr/include/php5/Zend -I/usr/include/php5/ext -I/usr/include/php5/ext/date/lib
checking for PHP extension directory... /usr/lib/php5/20090626
checking for PHP installed headers prefix... /usr/include/php5
checking if debug is enabled... no
checking if zts is enabled... no
checking for re2c... re2c
checking for re2c version... 0.13.5 (ok)
checking for gawk... no
checking for nawk... nawk
checking if nawk is broken... no
checking whether to enable apd support... yes, shared
checking for a sed that does not truncate output... (cached) /bin/sed
checking for fgrep... /bin/grep -F
checking for ld used by cc... /usr/bin/ld
checking if the linker (/usr/bin/ld) is GNU ld... yes
checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B
checking the name lister (/usr/bin/nm -B) interface... BSD nm
checking whether ln -s works... yes
checking the maximum length of command line arguments... 1572864
checking whether the shell understands some XSI constructs... yes
checking whether the shell understands "+="... yes
checking for /usr/bin/ld option to reload object files... -r
checking for objdump... objdump
checking how to recognize dependent libraries... pass_all
checking for ar... ar
checking for strip... strip
checking for ranlib... ranlib
checking command to parse /usr/bin/nm -B output from cc object... ok
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking for dlfcn.h... yes
checking for objdir... .libs
checking if cc supports -fno-rtti -fno-exceptions... no
checking for cc option to produce PIC... -fPIC -DPIC
checking if cc PIC flag -fPIC -DPIC works... yes
checking if cc static flag -static works... yes
checking if cc supports -c -o file.o... yes
checking if cc supports -c -o file.o... (cached) yes
checking whether the cc linker (/usr/bin/ld -m elf_x86_64) supports shared libraries... yes
checking whether -lc should be explicitly linked in... no
checking dynamic linker characteristics... GNU/Linux ld.so
checking how to hardcode library paths into programs... immediate
checking whether stripping libraries is possible... yes
checking if libtool supports shared libraries... yes
checking whether to build shared libraries... yes
checking whether to build static libraries... no
configure: creating ./config.status
config.status: creating config.h
config.status: executing libtool commands

root@sixsigma:/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1# make
/bin/bash /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/libtool --mode=compile cc  -I. -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1 -DPHP_ATOM_INC -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/include -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/main -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1 -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/TSRM -I/usr/include/php5/Zend -I/usr/include/php5/ext -I/usr/include/php5/ext/date/lib  -DHAVE_CONFIG_H  -g -O2   -c /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/php_apd.c -o php_apd.lo
libtool: compile:  cc -I. -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1 -DPHP_ATOM_INC -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/include -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/main -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1 -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/TSRM -I/usr/include/php5/Zend -I/usr/include/php5/ext -I/usr/include/php5/ext/date/lib -DHAVE_CONFIG_H -g -O2 -c /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/php_apd.c  -fPIC -DPIC -o .libs/php_apd.o
/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/php_apd.c: In function âapd_dump_fprintfâ:
/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/php_apd.c:182: warning: ignoring return value of âwriteâ, declared with attribute warn_unused_result
/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/php_apd.c: In function âapd_pprof_fprintfâ:
/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/php_apd.c:205: warning: format not a string literal and no format arguments
/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/php_apd.c: In function âapd_interactiveâ:
/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/php_apd.c:241: warning: ignoring return value of âwriteâ, declared with attribute warn_unused_result
/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/php_apd.c: In function âzif_override_functionâ:
/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/php_apd.c:615: warning: âzend_get_parameters_exâ is deprecated (declared at /usr/include/php5/Zend/zend_API.h:222)
/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/php_apd.c: In function âzif_rename_functionâ:
/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/php_apd.c:669: warning: âzend_get_parameters_exâ is deprecated (declared at /usr/include/php5/Zend/zend_API.h:222)
/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/php_apd.c: In function âzif_apd_set_pprof_traceâ:
/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/php_apd.c:792: warning: âzend_get_parameters_exâ is deprecated (declared at /usr/include/php5/Zend/zend_API.h:222)
/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/php_apd.c: In function âzif_apd_echoâ:
/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/php_apd.c:934: warning: ignoring return value of âwriteâ, declared with attribute warn_unused_result
/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/php_apd.c:935: warning: ignoring return value of âwriteâ, declared with attribute warn_unused_result
/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/php_apd.c: In function âapd_zend_startupâ:
/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/php_apd.c:967: error: âstruct _zend_compiler_globalsâ has no member named âextended_infoâ
make: *** [php_apd.lo] Error 1

I searched for building pecl apd but didn’t turn up anything useful. I had a look at the code in php_apd.c on line 967:

int apd_zend_startup(zend_extension *extension)
{
  TSRMLS_FETCH();
  CG(extended_info) = 1;  /* XXX: this is ridiculous */
  return zend_startup_module(&apd_module_entry);
}

The problem line was the line saying “this is ridiculous”. I wonder what they meant?

I decided to figure out where CG was defined so I could figure out what was going on. I grepped for CG:

root@sixsigma:/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1# grep -R "define CG" *
root@sixsigma:/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1# 

No dice. I had a look in the Makefile and found phpincludedir = /usr/include/php5.

jj5@sixsigma:~$ cd /usr/include/php5
jj5@sixsigma:/usr/include/php5$ ls
ext  main  TSRM  Zend
jj5@sixsigma:/usr/include/php5$ grep -R "define CG" *
Zend/zend_globals_macros.h:# define CG(v) TSRMG(compiler_globals_id, zend_compiler_globals *, v)
Zend/zend_globals_macros.h:# define CG(v) (compiler_globals.v)

The code in question was:

/* Compiler */
#ifdef ZTS
# define CG(v) TSRMG(compiler_globals_id, zend_compiler_globals *, v)
int zendparse(void *compiler_globals);
#else
# define CG(v) (compiler_globals.v)
extern ZEND_API struct _zend_compiler_globals compiler_globals;
int zendparse(void);
#endif

I wasn’t sure if ZTS was defined or not, but in any event the problem seemed to be related to *zend_compiler_globals.

root@sixsigma:/usr/include/php5# grep -R compiler_global *
Zend/zend_globals_macros.h:typedef struct _zend_compiler_globals zend_compiler_globals;
Zend/zend_globals_macros.h:# define CG(v) TSRMG(compiler_globals_id, zend_compiler_globals *, v)
Zend/zend_globals_macros.h:int zendparse(void *compiler_globals);
Zend/zend_globals_macros.h:# define CG(v) (compiler_globals.v)
Zend/zend_globals_macros.h:extern ZEND_API struct _zend_compiler_globals compiler_globals;
Zend/zend_globals.h:ZEND_API extern int compiler_globals_id;
Zend/zend_globals.h:struct _zend_compiler_globals {

I found the struct definition in Zend/zend_globals.h. I had a look at the source. It was a huge file. I searched for “extend” (because the error message was about missing member “extended_info”) and all I found was:

        /* for extended information support */
        zend_bool no_extensions;

Maybe I had an older version of the header file and it had been refactored from “no_extensions” to “extended_info”? That might explain why the comment was complaining about something being ridiculous. Maybe they rename their interface all the time? I tried changing php_apd.c to use “no_extensions” instead of “extended_info” but that didn’t compile either. Not knowing what else to do I commented out the line wtih the syntax error:

int apd_zend_startup(zend_extension *extension)
{
  TSRMLS_FETCH();
  /* CG(extended_info) = 1;  /* XXX: this is ridiculous */
  return zend_startup_module(&apd_module_entry);
}

Then I ran make again:

root@sixsigma:/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1# make
/bin/bash /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/libtool --mode=compile cc  -I. -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1 -DPHP_ATOM_INC -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/include -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/main -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1 -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/TSRM -I/usr/include/php5/Zend -I/usr/include/php5/ext -I/usr/include/php5/ext/date/lib  -DHAVE_CONFIG_H  -g -O2   -c /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/php_apd.c -o php_apd.lo
libtool: compile:  cc -I. -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1 -DPHP_ATOM_INC -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/include -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/main -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1 -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/TSRM -I/usr/include/php5/Zend -I/usr/include/php5/ext -I/usr/include/php5/ext/date/lib -DHAVE_CONFIG_H -g -O2 -c /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/php_apd.c  -fPIC -DPIC -o .libs/php_apd.o
/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/php_apd.c: In function âapd_dump_fprintfâ:
/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/php_apd.c:182: warning: ignoring return value of âwriteâ, declared with attribute warn_unused_result
/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/php_apd.c: In function âapd_pprof_fprintfâ:
/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/php_apd.c:205: warning: format not a string literal and no format arguments
/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/php_apd.c: In function âapd_interactiveâ:
/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/php_apd.c:241: warning: ignoring return value of âwriteâ, declared with attribute warn_unused_result
/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/php_apd.c: In function âzif_override_functionâ:
/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/php_apd.c:615: warning: âzend_get_parameters_exâ is deprecated (declared at /usr/include/php5/Zend/zend_API.h:222)
/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/php_apd.c: In function âzif_rename_functionâ:
/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/php_apd.c:669: warning: âzend_get_parameters_exâ is deprecated (declared at /usr/include/php5/Zend/zend_API.h:222)
/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/php_apd.c: In function âzif_apd_set_pprof_traceâ:
/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/php_apd.c:792: warning: âzend_get_parameters_exâ is deprecated (declared at /usr/include/php5/Zend/zend_API.h:222)
/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/php_apd.c: In function âzif_apd_echoâ:
/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/php_apd.c:934: warning: ignoring return value of âwriteâ, declared with attribute warn_unused_result
/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/php_apd.c:935: warning: ignoring return value of âwriteâ, declared with attribute warn_unused_result
/bin/bash /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/libtool --mode=compile cc  -I. -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1 -DPHP_ATOM_INC -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/include -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/main -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1 -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/TSRM -I/usr/include/php5/Zend -I/usr/include/php5/ext -I/usr/include/php5/ext/date/lib  -DHAVE_CONFIG_H  -g -O2   -c /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/apd_lib.c -o apd_lib.lo
libtool: compile:  cc -I. -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1 -DPHP_ATOM_INC -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/include -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/main -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1 -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/TSRM -I/usr/include/php5/Zend -I/usr/include/php5/ext -I/usr/include/php5/ext/date/lib -DHAVE_CONFIG_H -g -O2 -c /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/apd_lib.c  -fPIC -DPIC -o .libs/apd_lib.o
/bin/bash /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/libtool --mode=compile cc  -I. -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1 -DPHP_ATOM_INC -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/include -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/main -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1 -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/TSRM -I/usr/include/php5/Zend -I/usr/include/php5/ext -I/usr/include/php5/ext/date/lib  -DHAVE_CONFIG_H  -g -O2   -c /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/apd_array.c -o apd_array.lo
libtool: compile:  cc -I. -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1 -DPHP_ATOM_INC -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/include -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/main -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1 -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/TSRM -I/usr/include/php5/Zend -I/usr/include/php5/ext -I/usr/include/php5/ext/date/lib -DHAVE_CONFIG_H -g -O2 -c /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/apd_array.c  -fPIC -DPIC -o .libs/apd_array.o
/bin/bash /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/libtool --mode=compile cc  -I. -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1 -DPHP_ATOM_INC -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/include -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/main -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1 -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/TSRM -I/usr/include/php5/Zend -I/usr/include/php5/ext -I/usr/include/php5/ext/date/lib  -DHAVE_CONFIG_H  -g -O2   -c /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/apd_summary.c -o apd_summary.lo
libtool: compile:  cc -I. -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1 -DPHP_ATOM_INC -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/include -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/main -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1 -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/TSRM -I/usr/include/php5/Zend -I/usr/include/php5/ext -I/usr/include/php5/ext/date/lib -DHAVE_CONFIG_H -g -O2 -c /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/apd_summary.c  -fPIC -DPIC -o .libs/apd_summary.o
/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/apd_summary.c: In function âapd_summary_output_footerâ:
/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/apd_summary.c:278: warning: unknown conversion type character â"â in format
/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/apd_summary.c:294: warning: passing argument 6 of âphp_basenameâ from incompatible pointer type
/usr/include/php5/ext/standard/php_string.h:128: note: expected âsize_t *â but argument is of type âint *â
/bin/bash /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/libtool --mode=link cc -DPHP_ATOM_INC -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/include -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/main -I/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1 -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/TSRM -I/usr/include/php5/Zend -I/usr/include/php5/ext -I/usr/include/php5/ext/date/lib  -DHAVE_CONFIG_H  -g -O2   -o apd.la -export-dynamic -avoid-version -prefer-pic -module -rpath /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/modules  php_apd.lo apd_lib.lo apd_array.lo apd_summary.lo
libtool: link: cc -shared  .libs/php_apd.o .libs/apd_lib.o .libs/apd_array.o .libs/apd_summary.o      -Wl,-soname -Wl,apd.so -o .libs/apd.so
libtool: link: ( cd ".libs" && rm -f "apd.la" && ln -s "../apd.la" "apd.la" )
/bin/bash /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/libtool --mode=install cp ./apd.la /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/modules
libtool: install: cp ./.libs/apd.so /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/modules/apd.so
libtool: install: cp ./.libs/apd.lai /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/modules/apd.la
libtool: finish: PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin:/usr/lib/surfraw:/sbin" ldconfig -n /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/modules
----------------------------------------------------------------------
Libraries have been installed in:
   /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/modules

If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the `-LLIBDIR'
flag during linking and do at least one of the following:
   - add LIBDIR to the `LD_LIBRARY_PATH' environment variable
     during execution
   - add LIBDIR to the `LD_RUN_PATH' environment variable
     during linking
   - use the `-Wl,-rpath -Wl,LIBDIR' linker flag
   - have your system administrator add LIBDIR to `/etc/ld.so.conf'

See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------

Build complete.
Don't forget to run 'make test'.

Success!

The build script said to run make test, so:

root@sixsigma:/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1# make test

Build complete.
Don't forget to run 'make test'.

PHP Warning:  PHP Startup: Invalid library (maybe not a PHP library) 'apd.so' in Unknown on line 0

Warning: PHP Startup: Invalid library (maybe not a PHP library) 'apd.so' in Unknown on line 0
PHP Warning:  PHP Startup: Invalid library (maybe not a PHP library) 'apd.so' in Unknown on line 0

Warning: PHP Startup: Invalid library (maybe not a PHP library) 'apd.so' in Unknown on line 0

=====================================================================
PHP         : /usr/bin/php
PHP_SAPI    : cli
PHP_VERSION : 5.3.2-1ubuntu4.11
ZEND_VERSION: 2.3.0
PHP_OS      : Linux - Linux sixsigma.blackbrick.com 2.6.33.5-rscloud #2 SMP Thu Jun 10 15:26:23 UTC 2010 x86_64
INI actual  : /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/tmp-php.ini
More .INIs  :
CWD         : /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1
Extra dirs  :
VALGRIND    : Not used
=====================================================================
TIME START 2012-01-10 04:13:08
=====================================================================
No tests were run.

That didn’t look good. There was complaints about an invalid apd.so library and no tests were run. What next?

I had a look in the Makefile for the “test: all” target:

test: all
        -@if test ! -z "$(PHP_EXECUTABLE)" && test -x "$(PHP_EXECUTABLE)"; then \
                INI_FILE=`$(PHP_EXECUTABLE) -d 'display_errors=stderr' -r 'echo php_ini_loaded_file();' 2> /dev/null`; \
                if test "$$INI_FILE"; then \
                        $(EGREP) -h -v $(PHP_DEPRECATED_DIRECTIVES_REGEX) "$$INI_FILE" > $(top_builddir)/tmp-php.ini; \
                else \
                        echo > $(top_builddir)/tmp-php.ini; \
                fi; \
                INI_SCANNED_PATH=`$(PHP_EXECUTABLE) -d 'display_errors=stderr' -r '$$a = explode(",\n", trim(php_ini_scanned_files())); echo $$a[0];' 2> /dev/null`; \
                if test "$$INI_SCANNED_PATH"; then \
                        INI_SCANNED_PATH=`$(top_srcdir)/build/shtool path -d $$INI_SCANNED_PATH`; \
                        $(EGREP) -h -v $(PHP_DEPRECATED_DIRECTIVES_REGEX) "$$INI_SCANNED_PATH"/*.ini >> $(top_builddir)/tmp-php.ini; \
                fi; \
                TEST_PHP_EXECUTABLE=$(PHP_EXECUTABLE) \
                TEST_PHP_SRCDIR=$(top_srcdir) \
                CC="$(CC)" \
                        $(PHP_EXECUTABLE) -n -c $(top_builddir)/tmp-php.ini $(PHP_TEST_SETTINGS) $(top_srcdir)/run-tests.php -n -c $(top_builddir)/tmp-php.ini -d extension_dir=$(top_builddir)/modules/ $(PHP_TEST_SHARED_EXTENSIONS) $(TESTS); \
        else \
                echo "ERROR: Cannot run tests without CLI sapi."; \
        fi

A little bit of tinkering and I was able to determine that the test script was running:

/usr/bin/php -n -c /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/tmp-php.ini -d open_basedir= -d output_buffering=0 -d memory_limit=-1 /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/run-tests.php -n -c /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/tmp-php.ini -d extension_dir=/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/modules/ -d extension=apd.so

I wasn’t quite sure where to begin with that, so I searched for the error message PHP Warning: PHP Startup: Invalid library (maybe not a PHP library) ‘apd.so’ in Unknown on line 0 which rendered Re: Problems Compiling (lots of) extensions with
php 5.1-beta3 – msg#00192
which suggested the problem was that APD was a Zend extension not a normal extension:

Aren’t tzhose Zend Extensions? So you would need to load them with
zend_extension = [full path] instead of extension = [filename].

I remembered way back in the original installation instructions something about configuring zend_extension… so I edited /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/tmp-php.ini and added the following:

 zend_extension = /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/modules/apd.so
 apd.dumpdir = /build/trace
 apd.statement_tracing = 0

Since I was using the zend_extension I edited the command line to remove all references to “extension” arguments:

/usr/bin/php -n -c /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/tmp-php.ini -d open_basedir= -d output_buffering=0 -d memory_limit=-1 /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/run-tests.php -n -c /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/tmp-php.ini

root@sixsigma:/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1# /usr/bin/php -n -c /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/tmp-php.ini -d open_basedir= -d output_buffering=0 -d memory_limit=-1 /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/run-tests.php -n -c /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/tmp-php.ini
ERROR: environment variable TEST_PHP_EXECUTABLE must be set to specify PHP executable!

So I set that variable:

root@sixsigma:/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1# TEST_PHP_EXECUTABLE=/usr/bin/php
root@sixsigma:/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1# /usr/bin/php -n -c /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/tmp-php.ini -d open_basedir= -d output_buffering=0 -d memory_limit=-1 /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/run-tests.php -n -c /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/tmp-php.ini
ERROR: environment variable TEST_PHP_EXECUTABLE must be set to specify PHP executable!
root@sixsigma:/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1# export TEST_PHP_EXECUTABLE
root@sixsigma:/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1# /usr/bin/php -n -c /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/tmp-php.ini -d open_basedir= -d output_buffering=0 -d memory_limit=-1 /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/run-tests.php -n -c /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/tmp-php.ini

=====================================================================
PHP         : /usr/bin/php
PHP_SAPI    : cli
PHP_VERSION : 5.3.2-1ubuntu4.11
ZEND_VERSION: 2.3.0
PHP_OS      : Linux - Linux sixsigma.blackbrick.com 2.6.33.5-rscloud #2 SMP Thu Jun 10 15:26:23 UTC 2010 x86_64
INI actual  : /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/tmp-php.ini
More .INIs  :
CWD         : /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1
Extra dirs  :
VALGRIND    : Not used
=====================================================================
TIME START 2012-01-10 04:43:34
=====================================================================
No tests were run.

Still no tests running. I had a read, a nice long read, of the /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/run-tests.php file. It seems to load an run *.phpt files. So I searched for pecl apd phpt files and found Patching a bug in a pecl extension which describes the *.phpt file format. So I created a test.phpt file:

--TEST--
Just testing.
--FILE--
<?php

apd_set_pprof_trace();

function a() { echo "a"; }
function b() { a(); echo "b"; }

a();
b();
a();
--EXPECT--
aaba

I ran the run-tests.php script again and checked the /build/trace directory for messages from APD, but there was nothing there. The tests hadn’t run.

I couldn’t be bothered figuring out the correct syntax for run-tests.php so I edited the file and changed line 824 from:

$test_dirs = array();

To:

$test_dirs = array( '.' );

Then I ran the tests again:

root@sixsigma:/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1# /usr/bin/php -n -c /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/tmp-php.ini -d open_basedir= -d output_buffering=0 -d memory_limit=-1 /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/run-tests.php -n -c /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/tmp-php.ini

=====================================================================
PHP         : /usr/bin/php
PHP_SAPI    : cli
PHP_VERSION : 5.3.2-1ubuntu4.11
ZEND_VERSION: 2.3.0
PHP_OS      : Linux - Linux sixsigma.blackbrick.com 2.6.33.5-rscloud #2 SMP Thu Jun 10 15:26:23 UTC 2010 x86_64
INI actual  : /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/tmp-php.ini
More .INIs  :
CWD         : /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1
Extra dirs  :
VALGRIND    : Not used
=====================================================================
TIME START 2012-01-10 05:05:06
=====================================================================
PASS Just testing. [test.phpt]
=====================================================================
TIME END 2012-01-10 05:05:06

=====================================================================
TEST RESULT SUMMARY
---------------------------------------------------------------------
Exts skipped    :    0
Exts tested     :   45
---------------------------------------------------------------------

Number of tests :    1                 1
Tests skipped   :    0 (  0.0%) --------
Tests warned    :    0 (  0.0%) (  0.0%)
Tests failed    :    0 (  0.0%) (  0.0%)
Expected fail   :    0 (  0.0%) (  0.0%)
Tests passed    :    1 (100.0%) (100.0%)
---------------------------------------------------------------------
Time taken      :    0 seconds
=====================================================================

We would like to send this report automatically to the
PHP QA team, to give us a better understanding of how
the test cases are doing. If you don't want to send it
immediately, you can choose "s" to save the report to
a file that you can send us later.
Do you want to send this report now? [Yns]: n

And they ran!

I checked the /build/trace directory, and there was a file there! The trace had worked!

root@sixsigma:/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1# cd /build/trace
root@sixsigma:/build/trace# ls
pprof.15345.0
root@sixsigma:/build/trace# head pprof.15345.0
#Pprof [APD] v1.0.1
caller=/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/test.php

END_HEADER
! 1 /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/test.php
& 1 main 2
+ 1 1 2
& 2 apd_set_pprof_trace 2
+ 2 1 2
@ 0 2 0 0 489

It took me a little while to find it, but eventually I found the pprofp script in the file /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/pprofp. So I ran it:

root@sixsigma:/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1# ./pprofp -r /build/trace/pprof.15345.0
bash: ./pprofp: /usr/local/bin/php: bad interpreter: No such file or directory

I needed to fix the registered interpreter. I changed it to /usr/bin/php.

root@sixsigma:/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1# ./pprofp -r /build/trace/pprof.15345.0
PHP:  syntax error, unexpected '=' in Unknown on line 7

Trace for /build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1/test.php
Total Elapsed Time = 0.00
Total System Time  = 0.00
Total User Time    = 0.00


         Real         User        System             secs/    cumm
%Time (excl/cumm)  (excl/cumm)  (excl/cumm) Calls    call    s/call  Memory Usage Name
--------------------------------------------------------------------------------------
84.9 0.00 0.00  0.00 0.00  0.00 0.00     1  0.0005   0.0005            0 apd_set_pprof_trace
12.8 0.00 0.00  0.00 0.00  0.00 0.00     3  0.0000   0.0000            0 a
1.4 0.00 0.00  0.00 0.00  0.00 0.00     1  0.0000   0.0000            0 b
0.9 0.00 0.00  0.00 0.00  0.00 0.00     1  0.0000   0.0006            0 main

It works!

So then all I had to do was configure my application under development to run apd, which I did. Then I ran the report on the trace file it generated:

root@sixsigma:/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1# ./pprofp -r /build/trace/pprof.15650.1
PHP:  syntax error, unexpected '=' in Unknown on line 7

Trace for /home/jj5/proj/aman/src/web/aman/config.php
Total Elapsed Time = 2.62
Total System Time  = 0.37
Total User Time    = 1.23


         Real         User        System             secs/    cumm
%Time (excl/cumm)  (excl/cumm)  (excl/cumm) Calls    call    s/call  Memory Usage Name
--------------------------------------------------------------------------------------
36.2 0.95 0.95  0.03 0.03  0.00 0.00     2  0.4737   0.4773            0 ob_end_flush
15.0 0.39 0.39  0.21 0.21  0.07 0.07  52388  0.0000   0.0000            0 sgen_word_xor
9.3 0.24 0.24  0.21 0.21  0.02 0.02  33504  0.0000   0.0000            0 sgen_word_add
6.0 0.16 0.16  0.18 0.18  0.06 0.06  16756  0.0000   0.0000            0 sgen_word_a
4.5 0.12 0.12  0.04 0.04  0.02 0.02  16756  0.0000   0.0000            0 sgen_word_b
4.3 0.11 0.11  0.10 0.10  0.01 0.01  16756  0.0000   0.0000            0 sgen_word_c
4.3 0.11 0.11  0.11 0.11  0.05 0.05  16756  0.0000   0.0000            0 sgen_word_d
3.4 0.09 0.09  0.07 0.07  0.04 0.04    34  0.0026   0.0026            0 mysqli->query
3.2 0.08 1.20  0.10 0.90  0.04 0.27  16752  0.0000   0.0001            0 SgenBlowfishCipher->do_round
2.2 0.06 0.06  0.07 0.07  0.00 0.00   175  0.0003   0.0003            0 dirname
1.3 0.04 0.04  0.03 0.03  0.00 0.00  4477  0.0000   0.0000            0 substr
1.1 0.03 0.03  0.03 0.03  0.01 0.01  4168  0.0000   0.0000            0 hexdec

And ob_end_flush had a massive 36% of the processing time! Not sure what to do, I tried changing my php.ini file setting output_buffering to 200,000:

#output_buffering = 4096
output_buffering = 200000

Then I ran my code again and examined the next trace:

root@sixsigma:/build/buildd/php5-5.3.2/pear-build-download/apd-1.0.1# ./pprofp -r /build/trace/pprof.15948.0
PHP:  syntax error, unexpected '=' in Unknown on line 7

Trace for /home/jj5/proj/aman/src/web/aman/config.php
Total Elapsed Time = 2.01
Total System Time  = 0.57
Total User Time    = 1.37


         Real         User        System             secs/    cumm
%Time (excl/cumm)  (excl/cumm)  (excl/cumm) Calls    call    s/call  Memory Usage Name
--------------------------------------------------------------------------------------
20.8 0.42 0.42  0.30 0.30  0.07 0.07  52388  0.0000   0.0000            0 sgen_word_xor
14.7 0.30 0.30  0.22 0.22  0.07 0.07  33504  0.0000   0.0000            0 sgen_word_add
9.2 0.18 0.18  0.15 0.15  0.05 0.05  16756  0.0000   0.0000            0 sgen_word_a
6.9 0.14 0.14  0.10 0.10  0.04 0.04  16756  0.0000   0.0000            0 sgen_word_c
6.5 0.13 0.13  0.07 0.07  0.03 0.03  16756  0.0000   0.0000            0 sgen_word_b
6.3 0.13 0.13  0.10 0.10  0.04 0.04  16756  0.0000   0.0000            0 sgen_word_d
4.6 0.09 0.09  0.04 0.04  0.05 0.05   175  0.0005   0.0005            0 dirname
4.4 0.09 1.35  0.07 0.98  0.07 0.36  16752  0.0000   0.0001            0 SgenBlowfishCipher->do_round
3.5 0.07 0.07  0.03 0.03  0.02 0.02     2  0.0348   0.0348            0 mysqli_connect
2.8 0.06 0.06  0.03 0.03  0.01 0.01   819  0.0001   0.0001            0 preg_replace
1.7 0.03 0.03  0.01 0.01  0.01 0.01  4477  0.0000   0.0000            0 substr
1.6 0.03 0.03  0.02 0.02  0.01 0.01   139  0.0002   0.0002            0 gettype
1.4 0.03 0.03  0.01 0.01  0.01 0.01  4168  0.0000   0.0000            0 hexdec
1.3 0.03 0.03  0.05 0.05  0.02 0.02    34  0.0008   0.0008            0 mysqli->query
1.1 0.02 0.03  0.01 0.01  0.01 0.01     2  0.0114   0.0153            0 ob_end_flush

So that configuration change seemed to have fixed that problem! Or maybe it was just an aberration?

In any event, I’ve found the reason for my sluggish site. It’s because I’ve been lazy and haven’t refactored pccipher yet. When I was doing the development work it was easiest to write the algorithm once and then define an interface for both the 32-bit and 64-bit versions of the code to implement. This meant that I had to do my math with functions rather than with operators, which is slooooow. Anyway, I knew that. I guess now that I can’t hide from it I’ll have to get around to fixing up that implementation and improving its performance.

I’m glad that was easy…