Пишем расширение для PHP

Для чего может понадобиться написать свое расширение?

  • Существенно повышается скорость исполнения кода
  • Защита существующего кода — код поставляется в виде бинарника
  • Работа с драйверами, «железом на прямую» или использование сторонних dll/so

При разработке данного мануала использовались ресурсы http://www.php-cpp.com и https://habr.com/post/98862/, а так-же ряд других.

  1. Попробуем на Ubuntu php 7.2

Скачиваем и шаблон для разработки расширения на cpp

git clone https://github.com/CopernicaMarketingSoftware/PHP-CPP.git
cd PHP-CPP
make

Получаем:

pavel@pavelpc:~/reserved/getcoding/phpcpp$ make                                                                                                                                                                                                                                
mkdir -p shared/common                                                                                                                                                                                                                                                         
mkdir -p shared/zend                                                                                                                                                                                                                                                           
g++ -Wall -c -std=c++11 -fvisibility=hidden -DBUILDING_PHPCPP -Wno-write-strings -MD -g -fpic -o shared/common/streambuf.o common/streambuf.cpp                                                                                                                                
g++ -Wall -c -std=c++11 -fvisibility=hidden -DBUILDING_PHPCPP -Wno-write-strings -MD -g -fpic -o shared/common/modifiers.o common/modifiers.cpp                                                                                                                                
g++ -Wall -c -std=c++11 -fvisibility=hidden -DBUILDING_PHPCPP -Wno-write-strings -MD -g `php-config --includes` -fpic -o shared/zend/inivalue.o zend/inivalue.cpp                                                                                                              
/bin/sh: 1: php-config: not found                                                                                                                                                                                                                                              
In file included from zend/inivalue.cpp:8:0:
zend/includes.h:40:10: fatal error: php.h: Нет такого файла или каталога
 #include <php.h>
          ^~~~~~~
compilation terminated.                                                                                                                                                                                                                                                        
Makefile:204: recipe for target 'shared/zend/inivalue.o' failed                                                                                                                                                                                                                
make: *** [shared/zend/inivalue.o] Error 1

Не хватает исходных кодов php. Скачиваем, предварительно узнав текущую версию:

pavel@pavelpc:~/reserved/getcoding/phpcpp$ php --version
PHP 7.2.7-0ubuntu0.18.04.2 (cli) (built: Jul  4 2018 16:55:24) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.2.7-0ubuntu0.18.04.2, Copyright (c) 1999-2018, by Zend Technologies

pavel@pavelpc:~/reserved/getcoding/phpcpp$ sudo apt-get install php7.2-dev

Снова пробуем make:

pavel@pavelpc:~/reserved/getcoding/phpcpp$ make
...
Build complete.
pavel@pavelpc:~/reserved/getcoding/phpcpp$ sudo make install

В папке Examples лежит несколько примеров. Попробуем скомпилировать so на основе FunctionReturnValue:

pavel@pavelpc:~/reserved/getcoding/phpcpp/Examples/FunctionReturnValue$ make
g++ -Wall -c -I. -O2 -std=c++11 -fpic -o functionreturnvalue.o functionreturnvalue.cpp
g++ -Wall -shared -O2  -o functionreturnvalue.so functionreturnvalue.o -lphpcpp

Подключим получившуюся библиотеку в php.ini:

pavel@pavelpc:~/reserved/getcoding/phpcpp/Examples/FunctionReturnValue$ php-config --extension-dir
/usr/lib/php/20170718
pavel@pavelpc:~/reserved/getcoding/phpcpp/Examples/FunctionReturnValue$ sudo cp functionreturnvalue.so /usr/lib/php/20170718

В php.ini добавим строчку:

extension=/usr/lib/php/20170718/functionreturnvalue.so

и выполним тестовый скрипт:

pavel@pavelpc:~/reserved/getcoding/phpcpp/Examples/FunctionReturnValue$ php -r 'echo my_return_value_function() . "\n";'
42

2. Теперь тоже самое на FreeBSD 10.3 и php 5.4

Сначала попробовал скопировать получившийся в Ubuntu so из Ubuntu на FreeBSD и подключить расширением. А вдруг заработает? Не заработало 😉

root@noc:/usr/local/etc/php # php --version
PHP Warning:  PHP Startup: Unable to load dynamic library '/usr/local/lib/php/20100525/functionreturnvalue.so' - Shared object "libphpcpp.so.2.1" not found, required by "functionreturnvalue.so" in Unknown on line 0

Warning: PHP Startup: Unable to load dynamic library '/usr/local/lib/php/20100525/functionreturnvalue.so' - Shared object "libphpcpp.so.2.1" not found, required by "functionreturnvalue.so" in Unknown on line 0
PHP 5.4.45 (cli) (built: Jan 31 2016 02:44:32) 
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2014 Zend Technologies

Тогда делаем всё тоже самое что и в п.1:

git clone https://github.com/CopernicaMarketingSoftware/PHP-CPP.git
cd PHP-CPP 
make

Ой:

root@noc:/home/pavel/PHP-CPP # make
make: "/usr/home/pavel/PHP-CPP/Makefile" line 35: Missing dependency operator
make: "/usr/home/pavel/PHP-CPP/Makefile" line 37: Need an operator
make: "/usr/home/pavel/PHP-CPP/Makefile" line 39: Need an operator
make: "/usr/home/pavel/PHP-CPP/Makefile" line 78: Need an operator
make: "/usr/home/pavel/PHP-CPP/Makefile" line 81: Need an operator
make: "/usr/home/pavel/PHP-CPP/Makefile" line 84: Need an operator
make: "/usr/home/pavel/PHP-CPP/Makefile" line 86: Need an operator
make: "/usr/home/pavel/PHP-CPP/Makefile" line 88: Need an operator
make: "/usr/home/pavel/PHP-CPP/Makefile" line 90: Need an operator
make: Fatal errors encountered -- cannot continue
make: stopped in /usr/home/pavel/PHP-CPP

Установим g++:

pkg install lang/gcc49

Во FreeBSD g++ называется clang++, можно сделать символическую ссылку:

ln /usr/bin/clang++ /usr/bin/g++

Снова попробовав make, видим те-же ошибки… Ну чтож, сделаем тогда свой Makefile:

root@noc:/home/pavel/PHP-CPP # cmake /home/gavnetadmin/PHP-CPP
-- Configuring done
-- Generating done
-- Build files have been written to: /home/gavnetadmin/PHP-CPP

Снова пробуем:

root@noc:/home/gavnetadmin/PHP-CPP # make
[  5%] Built target phpcpp-common
[  8%] Building CXX object CMakeFiles/phpcpp.dir/zend/base.cpp.o
In file included from /home/gavnetadmin/PHP-CPP/zend/base.cpp:8:
/home/gavnetadmin/PHP-CPP/zend/includes.h:40:10: fatal error: 'php.h' file not found
#include <php.h>
         ^
1 error generated.
*** Error code 1

Stop.
make[2]: stopped in /usr/home/gavnetadmin/PHP-CPP
*** Error code 1

Stop.
make[1]: stopped in /usr/home/gavnetadmin/PHP-CPP
*** Error code 1

Stop.
make: stopped in /usr/home/gavnetadmin/PHP-CPP

Продолжение следует… Буду обновлять FreeBSD до актуальной версии и иставить php 7.


Комментарии:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.