Пишем своё расширение PHP на C. Часть 1: Linux
Очень часто бывает так, что встроенного в PHP набора функций недостаточно, или алгоритм выполняется слишком долго. Также возможен случай, когда надо запрограммировать какой-нибудь уникальный алгоритм. Тогда одним из вариантов будет написание собственного расширения для PHP.Эту статью я разделил на две части. Первая будет посвящена компилированию своего расширения на платформе Linux, а вторая компилированию на Windows. Мы будем делать простое расширение, которое добавляет одну функцию hello_world(), которая выводит сообщение “Hello extension loaded succesfull!”.
Тут некоторые наверное спросят, а зачем всё это делать, ведь в интернете полно руководств, как писать своё расширение. Так то оно так, но ни один из этих мануалов в конечном счёте не помог мне его скомпилить. Так что выкладываю здесб работающую (на данный момент) последовательность.
Бинарные библиотеки данного расширенимя скомпилированы под php 5.2.x
Под php 5.3.x работать не будет. Скорее всего необходима перекомпиляция вместе с бинарниками и исходниками соответствующей версии php на целевой платформе.
Для удобства я написал скриптик, который сам компилит исходники библиотеки, так что не буду расписывать алгоритм по шагам, а просто выложу исходники. В конце статьи вы найдёте архив со всеми файлами.
compile.sh
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
#!/bin/bash # Building script for Hello World extension (Ubuntu) phpize sudo ./configure --enable-hello make rm /usr/lib/php5/20060613/hello.so cp ./modules/hello.so /usr/lib/php5/20060613/ /etc/init.d/apache2 restart # clear mkdir ./backup cp ./config.m4 ./backup/config.m4 cp ./php_hello.h ./backup/php_hello.h cp ./php_hello.c ./backup/php_hello.c cp ./compile.sh ./backup/compile.sh make clean rm ./* rm ./autom4te.cache/* rmdir autom4te.cache rm ./build/* rmdir build rm ./include/* rmdir include rm ./module/* rmdir modules rm .deps cp ./backup/config.m4 ./config.m4 cp ./backup/php_hello.h ./php_hello.h cp ./backup/php_hello.c ./php_hello.c cp ./backup/compile.sh ./compile.sh rm ./backup/* rmdir backup echo '--------------------------------------------------' echo '| Library Compiled! |'; echo '| 1. Copy hello.so to your php extensions dir |'; echo '| for example (/usr/lib/php5/20060613/) |'; echo '| 2. Add line extension=hello.so to |'; echo '| (/usr/local/Zend/Optimizer/etc/php.ini) |'; echo '| 3. Restart Apache (/etc/init.d/apache2 restart) |'; echo ' 4. You can use function hello_world() for test |'; echo '--------------------------------------------------'; |
config.m4
1 2 3 4 5 6 |
PHP_ARG_ENABLE(hello, whether to enable HelloWorld support, [ --enable-hello Enable HelloWorld support]) if test "$PHP_HELLO" = "yes"; then AC_DEFINE(HAVE_HELLO, 1, [Whether you have Hello]) PHP_NEW_EXTENSION(hello, php_hello.c, $ext_shared) fi |
php_hello.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
#ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "php_hello.h" static function_entry hello_functions[] = { PHP_FE(hello_world, NULL) {NULL, NULL, NULL} }; zend_module_entry hello_module_entry = { #if ZEND_MODULE_API_NO >= 20010901 STANDARD_MODULE_HEADER, #endif PHP_HELLO_WORLD_EXTNAME, hello_functions, NULL, NULL, NULL, NULL, NULL, #if ZEND_MODULE_API_NO >= 20010901 PHP_HELLO_WORLD_VERSION, #endif STANDARD_MODULE_PROPERTIES }; #ifdef COMPILE_DL_HELLO ZEND_GET_MODULE(hello) #endif PHP_FUNCTION(hello_world) { RETURN_STRING("Hello extension loaded succesfull!", 1); } |
php_hello.h
1 2 3 4 5 6 7 8 9 10 11 12 |
#ifndef PHP_HELLO_H #define PHP_HELLO_H 1 #define PHP_HELLO_WORLD_VERSION "1.0" #define PHP_HELLO_WORLD_EXTNAME "hello" PHP_FUNCTION(hello_world); extern zend_module_entry hello_module_entry; #define phpext_hello_ptr &hello_module_entry #endif |
open suse, php 5.4.6
при make вываливается в
/var/packages/php-5.4.6/ext/hello/hello.c:8: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘hello_functions’
/var/packages/php-5.4.6/ext/hello/hello.c:18: error: ‘hello_functions’ undeclared here (not in a function)
make: *** [hello.lo] Error 1