Home >Backend Development >PHP Tutorial >A brief discussion on the development of PHP Extension - Basics Page 1/2_PHP Tutorial

A brief discussion on the development of PHP Extension - Basics Page 1/2_PHP Tutorial

WBOY
WBOYOriginal
2016-07-21 15:33:27924browse

Summary & Introduction
PHP is a language that is currently widely used. It can be seen in various large, medium and small websites from foreign Facebook and Twitter to domestic Taobao, Tencent, Baidu and all kinds of large, medium and small websites on the Internet. . It should be said that the success of PHP relies largely on its open extension API mechanism and rich extension components (PHP Extension). It is these extension components that allow PHP to operate from various database operations to XML, JSON, encryption, file processing, It is omnipotent in fields such as graphics processing and Socket. Sometimes developers may need to develop their own PHP extensions. The current extension mechanism of PHP5 is based on Zend API. Zend API provides rich interfaces and macro definitions, plus some practical tools, making it not particularly difficult to develop PHP extensions. . This article will introduce basic knowledge about the development of PHP extension components, and demonstrate the basic process of developing PHP extensions through an example.

The development process of PHP extension components is different in Unix and Windows environments, but they are basically interoperable. This article will be based on the Unix environment (specifically using Linux). Reading this article requires a simple understanding of some basic knowledge of the Unix environment, PHP and C language. As long as you have a simple understanding, I will try not to cover too specific operating system and language features, and explain them where necessary to facilitate readers' reading.

The specific development environment of this article is Ubuntu 10.04 + PHP 5.3.3.

Download PHP source code
To develop PHP extensions, the first step is to download the PHP source code, because it contains the tools needed to develop extensions. What I downloaded is the latest version of PHP 5.3.3, in the format of tar.bz2 compressed package. The download address is: http://cn.php.net/get/php-5.3.3.tar.bz2/from/a/mirror.

After downloading, move the source code to the appropriate directory and unzip it. The decompression command is:

Copy code The code is as follows:
tar -jxvf Source package name

If you downloaded tar .gz compressed package, the decompression command is
Copy code The code is as follows:
tar -zxvf source package name

After decompression, there is an ext directory in the source code directory, which is the directory related to PHP extensions. After entering the directory and viewing it with ls, you can see many existing extensions. The picture below is the result of viewing it in my environment:


image

The blue ones are expansion pack directories, in which you can see the familiar mysql, iconv, gd, etc. ext_skel is a script tool used to automatically generate PHP extension framework in Unix environment. We will use it soon. ext_skel_win32.php is the corresponding script under Windows.

Develop your own PHP extension - say_hello
Let's develop a PHP extension: say_hello. This extension is very simple, it just accepts a string parameter and outputs "Hello xxx!". This example is only to introduce the development process of PHP extension components and does not assume actual functions.

Generate extension component framework
PHP’s extension component development directory and files have a fixed organizational structure. You can just enter an existing extension component directory and view all its files. I think you must be dazzled. . Of course you can choose to build the framework manually, but I believe you would rather have something do it for you. The ext_skel script mentioned above is a tool used to automatically build the extension package framework. The complete command of ext_skel is:

ext_skel --extname=module [--proto=file] [--stubs=file] [--xml[=file]] [--skel=dir] [- -full-xml] [--no-help]

As beginners, we don’t have to know all the command parameters. In fact, in most cases, we only need to provide the first parameter, which is the expansion The name of the module. Therefore, we type the following command in the ext directory:
./ext_skel --extname=say_hello

(If you want to learn more about the various command parameters of ext_skel, please refer here)

At this time, use ls to view it, and you will find that there is an additional "say_hello" directory. Enter this directory, and you will find that ext_skel has established the basic framework of say_hello for us, as shown below:

image

If you are too lazy to figure out the entire contents of the PHP extension package directory structure, then there are three files in it that you must pay attention to:

config.m4: This is the Build System configuration file in the Unix environment, which will be used to generate configuration and installation later.

php_say_hello.h: This file is the header file of the extension module. Following the consistent style of C language, some custom structures, global variables, etc. can be placed in this.

say_hello.c: This is the main program file of the extension module. The final function entries of the extension module are here. Of course, you can stuff all the program code into it, or you can follow the modular idea and put each functional module into different files.

The following content mainly revolves around these three files.

Unix Build System Configuration

The first step in developing PHP extension components is not to write the implementation code, but to configure the Build System option first. Since we are developing under Linux, the configuration here is mainly related to config.m4.

Regarding the Build System configuration, if I can write a lot about it, and it is related to many things in the Unix system, even if I am interested in writing it, I guess no one will be interested in reading it, so we will omit it here and only focus on the key points. For more details about config.m4, please refer here.

Open the generated config.m4 file, the content is roughly as follows:

Copy the code The code is as follows:

dnl $Id$
dnl config.m4 for extension say_hello
dnl Comments in this file start with the string 'dnl'.
dnl Remove where necessary. This file will not work
dnl without editing.
dnl If your extension references something external, use with:
dnl PHP_ARG_WITH(say_hello, for say_hello support,
dnl Make sure that the comment is aligned:
dnl [ --with-say_hello Include say_hello support])
dnl Otherwise use enable:
dnl PHP_ARG_ENABLE(say_hello, whether to enable say_hello support,
dnl Make sure that the comment is aligned:
dnl [ --enable-say_hello Enable say_hello support])
if test "$PHP_SAY_HELLO" != "no"; then
dnl Write more examples of tests here...
dnl # --with-say_hello -> check with-path
dnl SEARCH_PATH="/usr/local /usr" # you might want to change this
dnl SEARCH_FOR="/include/say_hello.h" # you most likely want to change this
dnl if test -r $PHP_SAY_HELLO/$SEARCH_FOR; then # path given as parameter
dnl SAY_HELLO_DIR=$PHP_SAY_HELLO
dnl else # search default path list
dnl AC_MSG_CHECKING([for say_hello files in default path])
dnl for i in $SEARCH_PATH ; do
dnl if test -r $i/$SEARCH_FOR; then
dnl SAY_HELLO_DIR=$i
dnl AC_MSG_RESULT(found in $i)
dnl fi
dnl done
dnl fi
dnl
dnl if test -z "$SAY_HELLO_DIR"; then
dnl AC_MSG_RESULT([not found])
dnl AC_MSG_ERROR([Please reinstall the say_hello distribution])
dnl fi
dnl # --with-say_hello -> add include path
dnl PHP_ADD_INCLUDE($SAY_HELLO_DIR/include)
dnl # --with-say_hello -> check for lib and symbol presence
dnl LIBNAME=say_hello # you may want to change this
dnl LIBSYMBOL=say_hello # you most likely want to change this
dnl PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL,
dnl [
dnl PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $SAY_HELLO_DIR/lib, SAY_HELLO_SHARED_LIBADD)
dnl AC_DEFINE(HAVE_SAY_HELLOLIB,1,[ ])
dnl ],[
dnl AC_MSG_ERROR([wrong say_hello lib version or lib not found])
dnl ],[
dnl -L$SAY_HELLO_DIR/lib -lm
dnl ])
dnl
dnl PHP_SUBST(SAY_HELLO_SHARED_LIBADD)
PHP_NEW_EXTENSION(say_hello, say_hello.c, $ext_shared)
fi

这个结构体可能看起来会让人有点头疼,不过我还是要解释一下里面的内容。因为这就是PHP Extension的原型,如果不搞清楚,就没法开发PHP Extension了。当然,我就不一一对每个字段进行解释了,只拣关键的、这篇文章会用到的字段说,因为许多字段并不需要我们手工填写,而是可以使用某些预定义的宏填充。

第7个字段“name”,这个字段是此PHP Extension的名字,在本例中就是“say_hello”。

第8个字段“functions”,这个将存放我们在此扩展中定义的函数的引用,具体结构不再分析,有兴趣的朋友可以阅读_zend_function_entry的源代码。具体编写代码时这里会有相应的宏。

第9-12个字段分别是四个函数指针,这四个函数会在相应时机被调用,分别是“扩展模块加载时”、“扩展模块卸载时”、“每个请求开始时”和“每个请求结束时”。这四个函数可以看成是一种拦截机制,主要用于相应时机的资源分配、释放等相关操作。

第13个字段“info_func”也是一个函数指针,这个指针指向的函数会在执行phpinfo()时被调用,用于显示自定义模块信息。

第14个字段“version”是模块的版本。

(关于zend_module_entry更详尽的介绍请参考这里)

介绍完以上字段,我们可以看看“say_hello.c”中自动生成的“say_hello_module_entry”框架代码了。

复制代码 代码如下:

/* {{{ say_hello_module_entry
*/
zend_module_entry say_hello_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
STANDARD_MODULE_HEADER,
#endif
"say_hello",
say_hello_functions,
PHP_MINIT(say_hello),
PHP_MSHUTDOWN(say_hello),
PHP_RINIT(say_hello), /* Replace with NULL if there's nothing to do at request start */
PHP_RSHUTDOWN(say_hello), /* Replace with NULL if there's nothing to do at request end */
PHP_MINFO(say_hello),
#if ZEND_MODULE_API_NO >= 20010901
"0.1", /* Replace with version number for your extension */
#endif
STANDARD_MODULE_PROPERTIES
};
/* }}} */

First of all, the macro "STANDARD_MODULE_HEADER" will generate the first 6 fields, and "STANDARD_MODULE_PROPERTIES" will generate the fields after "version", so we don't have to worry about it yet. The several fields we care about have also been filled in or generated by macros, and the frameworks of several functions have also been generated at the corresponding locations in "say_hello.c". It should be noted here that the parameters of several macros are all "say_hello", but this does not mean that the names of several functions are all "say_hello", and there is no function name overloading mechanism in C language. In fact, in the process of developing PHP Extension, various macros predefined in Zend are used almost everywhere, from global variables to function definitions and even return values. C language cannot be written in a "naked" way. , this is because the operating mechanism of PHP may cause problems such as naming conflicts, and these macros will transform elements such as functions into an internal name, but these are transparent to programmers (unless you read the code of those macros), We program through various macros, and macros handle a lot of internal stuff for us.

After writing this, our task is clear: first, if we need to process something at the corresponding time, we need to fill in the contents of each interception function; second, write the function function of say_hello and add the reference to say_hello_functions .

Write phpinfo() callback function

Because the say_hello extension does not require operations at each life cycle stage, we only write the content of info_func. As mentioned above, this function will be automatically called when phpinfo() is executed to display extension information. Four functions will be used to write this function:

php_info_print_table_start()——Start phpinfo table. No parameters.

php_info_print_table_header()——Output table header. The first parameter is an integer, indicating the number of columns in the header, and the subsequent parameters are (char*) type parameters equal to the number of columns used to specify the text to be displayed.

php_info_print_table_row()——Output table content. The first parameter is an integer, indicating the number of columns in this row, and the subsequent parameters are (char*) type parameters equal to the number of columns used to specify the text to be displayed.

php_info_print_table_end()——End the phpinfo table. No parameters.

www.bkjia.comtruehttp: //www.bkjia.com/PHPjc/322589.htmlTechArticleAbstract then dnl Write more examples of tests here... dnl # --with-say_hello - check with-path dnl SEARCH_PATH="/usr/local /usr" # you might want to change this dnl SEARCH_FOR="/incl...
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn