
Intro
El proyecto PHP-CPP te permite compilar tu propia extensión en C++. Estas notas son los pasos que tuve que seguir para conseguir hacer funcionar el típico Hola mundo.
Manos a la obra
Las pruebas las hice en Ubuntu 14.04. Previamente intenté hacerlo en un Ubuntu
12.04 (porque un servidor tenía esa versión) pero el compilador que trae es
muy viejo y al ejecutar make el proceso falla con el siguiente mensaje:
error: unrecognized command line option "-std=c++11"
Después de mucho buscar encontré esta pregunta en StackOverflow. Básicamente el error se debe a que el compilador de Ubuntu 12.04 es muy viejo. Es posible instalar un compilador más reciente, pero vale mejor aprovechar el tiempo para actualizar la máquina a Ubuntu 14.04.
El primer paso es instalar compiladores, librerías y utilidades:
sudo aptitude install php5-dev build-essential git
Luego clonamos el repo de PHP-CPP, corremos make y make install.
git clone https://github.com/CopernicaMarketingSoftware/PHP-CPP.git
make
sudo make install
El Makefile es lo suficientemente inteligente como para averiguar el lugar
correcto dónde poner las librerías. Después de compilar e instalar PHP-CPP es
momento de compilar una extensión de PHP para comprobar que todo funciona
bien. Basado en el tutorial de
PHP-CPP usé los
archivos: main.cpp, Makefile y noe_extension.ini.
El Makefile se ve así:
NAME = noe_extension INI_DIR = /etc/php5/mods-available/ EXTENSION_DIR = $(shell php-config --extension-dir) EXTENSION = ${NAME}.so INI = ${NAME}.ini COMPILER = g++ LINKER = g++ COMPILER_FLAGS = -Wall -c -O2 -std=c++11 -fpic -o LINKER_FLAGS = -shared LINKER_DEPENDENCIES = -lphpcpp RM = rm -f CP = cp -f MKDIR = mkdir -p SOURCES = $(wildcard *.cpp) OBJECTS = $(SOURCES:%.cpp=%.o) all: ${OBJECTS} ${EXTENSION} ${EXTENSION}: ${OBJECTS} ${LINKER} ${LINKER_FLAGS} -o $@ ${OBJECTS} ${LINKER_DEPENDENCIES} ${OBJECTS}: ${COMPILER} ${COMPILER_FLAGS} $@ ${@:%.o=%.cpp} install: ${CP} ${EXTENSION} ${EXTENSION_DIR} ${CP} ${INI} ${INI_DIR} clean: ${RM} ${EXTENSION} ${OBJECTS}
El archivo main.cpp se ve así:
#include <stdlib.h> #include <phpcpp.h> Php::Value hello() { return "Hola Mundo"; } Php::Value myFunction() { if (rand() % 2 == 0) { return "string"; } else { return 123; } } /** * tell the compiler that the get_module is a pure C function */ extern "C" { /** * Function that is called by PHP right after the PHP process * has started, and that returns an address of an internal PHP * structure with all the details and features of your extension * * @return void* a pointer to an address that is understood by PHP */ PHPCPP_EXPORT void *get_module() { // static(!) Php::Extension object that should stay in memory // for the entire duration of the process (that's why it's static) static Php::Extension extension("noe_extension", "1.0"); // @todo add your own functions, classes, namespaces to the extension extension.add("hello", hello); extension.add("myFunction", myFunction); // return the extension return extension; } }
Finalmente, noe_extension.ini:
extension=noe_extension.so
Ya solo falta compilar e instalar:
make
sudo make install
El Makefile anterior (o sea, el segundo) también es lo suficientemente
inteligente como para averiguar el lugar correcto dónde poner la librería
compilada (noe_extension.so) y el archivo noe_extension.ini. En el Ubuntu
14.04 donde probé esto los archivos quedaron en estas dos rutas:
/usr/lib/php5/20121212/noe_extension.so/etc/php5/mods-available/noe_extension.ini
Aunque la localización de noe_extension.ini es la correcta, hay que saber
que el estilo de configuración de las extensiones de PHP en Debian/Ubuntu es
muy parecido al de sitios y módulos de Apache 2. En Ubuntu/Debian hay que usar
los comandos a2enconf, a2enmod y a2ensite para activar algún archivo con
extensión .conf en particular. De igual manera, en Debian/Ubuntu también
existen los comandos php5enmod y phpdismod. Usé php5enmod para dar mi
módulo de alta:
sudo php5enmod noe_extension
Esto crea una liga simbólica /etc/php5/apache2/conf.d/20-noe_extension.ini
que apunta hacia /etc/php5/mods-available/noe_extension.ini. Después de esto
reiniciamos Apache:
sudo service apache2 restart
Después de esto, sólo faltó escribir un pequeño script de PHP para usar la
extensión. Lo puse en un directorio visible por Apache 2 y lo nombré
index.php:
<html> <head> <title>Extensión de PHP de Noe</title> </head> <body> <h3>Extensión de PHP de Noe</h3> <ul> <li>Hola: <?php echo (hello()); ?> </li> <li>MyFunction: <?php echo myFunction(); ?></li> </ul> </body> </html>
Y si la configuración es correcta, se deberá ver algo así:

Los textos «Hola Mundo» y «string» provienen del complemento noe_extension.so.
FIN
La imagen «extension cord» proviene de http://pixabay.com/en/extension-cord-cable-electronics-147580/. Tomada el día 13 de marzo del 2015.