How to Develop a PHP Extension Quickly Based on PHP-X

  c++, extend, php, php-x, zend-api

PHP-XI was there2017A new project was created in early 2002. The goal of this project is toLet have certain working experiencePHPPrograms can have the ability to expand development..

0x00 original intention

From2012Started writing inswoole, now calculate to already have5It’s been 12 years. I find it very difficult to write a PHP extension. In the PHP programmer community, it can even be said that it is difficult to find a person who can write PHP extensions. PHP officials are very unfriendly to extension developers, as provided in the source codeZend APIIt is extremely difficult to use.APIComplex and messy, filled with all kinds of macro writing.Zend APIThere are so many pits that ordinary developers can easily step into them. There are all kinds of puzzlingcore dumpQuestion.Zend APIThere are few documents, and developers need to spend a lot of learning time if they really want to master this skill.

So I came up with a new idea this year, based on my writingswooleExpand beyond5Years of experience, I tried toZend APIAndC++Establish a packaging layer between, letPHPExpanding development becomes simple. There is a certainC++BasicPHPerCan easily develop aPHPExpansion.

PHP-XThis project was born in this way and took only one month to develop. Its development efficiency is very high, and only one of them works in our company.3PHP programmers in 2005 can make an extension. After that, it was quickly verified in several projects of the company. In3A large number of crashes and memory leaks have been fixed in 24 hours. At present, the stability, performance and robustness have all reached the industrial level.

0x01 Start

PHP-XBased on itselfC++11Develop, usecmakeCompile and configure. First, you need to make sure all dependencies are installed. These include:

  • Gcc-4.8 or later
  • Php-7.0 or later, requiresphp7-devpackage
  • Cmake-2.8 or later

Then installPHP-X.

git clone  https://github.com/swoole/PHP-X.git
 cd PHP-X
 cmake .
 make -j 4
 sudo make install

There are no compilation errors and will be compiled successfully.libphpx.so, and installed to the of the systemlibDirectory. The header file will be copied to the systemincludeDirectory. This requires executionsudo ldconfigRefreshsoFile cache.

0x02 New Project

Use any development tool to create a new onetest.ccSource file. First need to introducephpx.hHead file. Then useusingintroducephpxThe namespace of the.PHPOfficial unusedC++, thereforephpxDirectly usedphpAs a namespace.

#include <phpx.h>
 using namespace std;
 using namespace php;

Create extended usePHPX_EXTENSIONMacro to implement. In this macro, you only need tonew ExtensionYou can create an extension. Construction method acceptance2Parameters, the first is the name of the extension, the second is the version number of the extension. InPHPX_EXTENSIONIn macroreturnPointer to this extended object.

PHPX_EXTENSION()
 {
 Extension *ext = new Extension("test", "0.0.1");
 return ext;
 }

It must be used here.new ExtensionAnd cannot create objects directly on the stack

0x03 Add Function

OnePHPThe main function of extension is to provide an extension functionC/C++Code implementation, so its performance will be better thanPHPThe performance of user functions is dozens or even hundreds of times higher. InphpxThe function implemented in is very simple. UsePHPX_FUNCTIONTo implement the extension function, and then call theExtension::registerFunctionTo register the extension function.

PHPX_FNIs an assistant macro, in fact is expanded"cpp_hello_world", cpp_hello_world
PHPX_FUNCTIONWhen expanded, includes2Variables, the first is a parameterargsThe second is the return valueretval
By operationargsAndretvalTwo variables can realize the input and output of the function

Our code here is very simple,cpp_test($str, $n)Call this function to return a$nA$strAn array of.

#include <phpx.h>
 using namespace std;
 using namespace php;
 
 //Declare Function
 PHPX_FUNCTION(cpp_test);
 
 PHPX_EXTENSION()
 {
 Extension *ext = new Extension("test", "0.0.1");
 ext->registerFunction(PHPX_FN(cpp_test));
 return ext;
 }
 
 //Implement Function
 PHPX_FUNCTION(cpp_test)
 {
 //args[1] is the second parameter of this extension function
 long n = args[1].toInt();
 
 //Initialize the return value retval as an array
 Array _array(retval);
 
 for(int i = 0;   i < n;  i++)
 {
 //args[0] is the first parameter of this extension function
 //append method means to append elements to the array
 _array.append(args[0]);
 }
 }

0x04 Compile Extension

Write aMakefileDocuments. The content is as follows:

PHP_INCLUDE = `php-config --includes`
 PHP_LIBS = `php-config --libs`
 PHP_LDFLAGS = `php-config --ldflags`
 PHP_INCLUDE_DIR = `php-config --include-dir`
 PHP_EXTENSION_DIR = `php-config --extension-dir`
 
 test.so: test.cc
 c++ -DHAVE_CONFIG_H -g -o test.so -O0 -fPIC -shared test.cc -std=c++11 ${PHP_INCLUDE} -I${PHP_INCLUDE_DIR} -lphpx
 
 install: test.so
 cp test.so ${PHP_EXTENSION_DIR}/
 clean:
 rm *.so

php-configThis tool isPHPProvided, usedphp-configAvailablePHPThe installation path, header file directory, extension directory, other additional compilation parameters, etc.

This ..MakefileSupport3Instructions,makeCompile,make cleanCleaning up,make installInstall to extended directory.

It may be necessary here.rootPermission to usesudo make installPerform installation
Copying directly from a web page may occurtabTabs are replaced with spaces, please edit them manually.MakefileUsetabIndent
MacOSThe next step is toc++Added to compilation parameters-undefined dynamic_lookup

It will be implemented after it is written.make install, the extension is compiled and extendedtest.soInstall toPHPIn the extended directory of. At this time need to modifyphp.inijoinextension=test.soLoad extension.

Usephp -mTo see if your extension loads properly.

php -m
 [PHP Modules]
 Core
 ctype
 curl
 date
 dom
 fileinfo
 filter
 gd
 hash
 iconv
 inotify
 json
 libxml
 mbstring
 mcrypt
 memcached
 mongodb
 mysqli
 mysqlnd
 openssl
 pcntl
 pcre
 PDO
 pdo_mysql
 pdo_sqlite
 Phar
 posix
 redis
 Reflection
 session
 SimpleXML
 sockets
 SPL
 sqlite3
 standard
 swoole
 test
 tokenizer
 xml
 xmlreader
 xmlwriter
 yac
 zlib
 zmq
 
 [Zend Modules]

See heretest, indicating that your extension has been successfully loaded and can be called nowcpp_testThis extension function.

0x05 execution

Write atest.php, the content is:

<?  php
 var_dump(cpp_test("hello", 3));

carry outtest.php

php  test.php
 array(3) {
 [0]=>
 string(5) "hello"
 [1]=>
 string(5) "hello"
 [2]=>
 string(5) "hello"
 }

It can be seen that the execution result meets the expectation. So congratulations, now you have successfully developed onePHPExpanded. Is it very simple?

0x06 More

The above example is still relatively simple, just write an extension function. To be truly used in actual projectsPHP-XYou still have a lot of work to do.

  • NeedC++Basic knowledge of
  • Learn morePHP-XTheAPI

In addition, it can be used together.EclipseWaitIDETools that can be implementedAPIAutomatic prompt and completion will be more convenient to develop.

Compared toZend API,PHP-XIt is much easier to use. I believe you won’t spend too much time mastering this skill. Next, I will write more tutorials to teach you how to use them.PHP-XRealize more complex functions such as extended classes, resources, callback functions, etc.