PHP is written in C. For every PHPer, there is an inner urge to write extensions. However, a good entry point is lacking. A Google search for PHP extensions is mostly a copy of the article, and some people have moved it to their blogs without even doing it. There are a few good tutorials, but they are from the PHP 5 era and have a lot of holes in them. I will record my own slow steps, maybe it will be a “tutorial” for others.

Build an extension

Many of you have seen many tutorials online. $./ext_skel –extname=extname However, when you clone the PHP source code, you will find that there is no ext/ext_skel file in the master branch. So, HERE’s my summary:

You can execute this command if you download the PHP source directly, or if the version is already released

$ cd ext
$ ./ext_skel --extname=extnameCopy the code

If you are directly in the master branch and only have the ext_skel.php file, then you can execute the PHP file directly

$ cd ext
$ php ext_skel.php --ext extnameCopy the code

Since I’m working directly under the Master branch, the rest is the default operation under the master.

After generating the extension, we should see four files and a folder. At this stage, we only need two files, the.c file and the.h file.

A small pit

After we have generated the extension, we can try to compile it

$ phpize
$ ./configure
$ make && make testCopy the code

We were surprised to see a warning at compile time.

warning: implicit declaration of function
      'ZEND_PARSE_PARAMETERS_NONE' is invalid in C99 [-Wimplicit-function-declaration]
        ZEND_PARSE_PARAMETERS_NONE();
        ^
1 warning generated.Copy the code

Then you run make test and one of the tests fails. That’s right, the script generated good files for us, but it didn’t pass its own tests. Do you think it’s weird. Let’s look at the details of warning. The function ZEND_PARSE_PARAMETERS_NONE could not be found. I looked at the file and found it on line 15. You can probably guess what it means by looking at the name of this function. So I did a search of the PHP source code. But we found such a macro definition.

#ifndef zend_parse_parameters_none
#define zend_parse_parameters_none()    \
        zend_parse_parameters(ZEND_NUM_ARGS(), "")
#endifCopy the code

After replacing the original uppercase, there is no warning. That’s kind of like the authorities digging a hole for us. I don’t know why the macro definition of uppercase returns an error.

Define a function

I think most people who write extensions want to implement at least one function, not just a few global variables

Here PHP provides us with a useful macro called PHP_FUNCTION. There are also two functions defined in the generated code, which can be used as references. This macro will eventually be translated into a function. For example, PHP_FUNCTION(name) will eventually be translated to void zif_name(zend_execute_data *execute_data, zval *return_value)

And we see that this array is defined

const zend_function_entry cesium_functions[] = {
    PHP_FE(cesium_test1,        arginfo_cesium_test1)
    PHP_FE(cesium_test2,        arginfo_cesium_test2)
    PHP_FE_END
};Copy the code

We need to add the newly added function to this array. Like this,

const zend_function_entry cesium_functions[] = {
    PHP_FE(cesium_test1,        arginfo_cesium_test1)
    PHP_FE(cesium_test2,        arginfo_cesium_test2)
    PHP_FE(name,           NULL)
    PHP_FE_END
};Copy the code

Remember, don’t end with a semicolon or comma. Finally, we can take this function and give it an output

PHP_FUNCTION(name)
{
    php_printf("Hello\n");
}Copy the code

After compiling and installing, we can use this function

conclusion

This article simply shows you the entire process from creating an extension to running it. Walk through the process with a running mentality.

Due to the author’s limited level, if there is any mistake, please feel free to comment.