• PHP扩展编写示例


    1、生成描述文件,包含对函数等的定义

    [chengyi@localhost php-extension]$ cat hello_cy.def

    string self_concat(string str, int n);

    2、进入PHP源码的ext目录

    [chengyi@localhost ext]$ pwd

    /home/chengyi/centos_soft_install/php-5.2.5/ext

    3、查看ext_skel的帮助,我们主要用到的是 --extname=module  定义将要生成的模块名称; --proto=file    指向刚才的描述函数定义的文件。

    [chengyi@localhost ext]$ ./ext_skel --help

    ./ext_skel --extname=module [--proto=file] [--stubs=file] [--xml[=file]]

               [--skel=dir] [--full-xml] [--no-help]

      --extname=module   module is the name of your extension

      --proto=file       file contains prototypes of functions to create

      --stubs=file       generate only function stubs in file

      --xml              generate xml documentation to be added to phpdoc-cvs

      --skel=dir         path to the skeleton directory

      --full-xml         generate xml documentation for a self-contained extension

                         (not yet implemented)

      --no-help          don't try to be nice and create comments in the code

                         and helper functions to test if the module compiled

    4、执行ext_skel,生成空模块

    [chengyi@localhost ext]$ ./ext_skel --extname=hello_cy --proto=/home/chengyi/test-all/php-extension/hello_cy.def  

    Creating directory hello_cy

    awk: /home/chengyi/centos_soft_install/php-5.2.5/ext/skeleton/create_stubs:56: warning: escape sequence `/|' treated as plain `|'

    Creating basic files: config.m4 config.w32 .cvsignore hello_cy.c php_hello_cy.h CREDITS EXPERIMENTAL tests/001.phpt hello_cy.php [done].

    To use your new extension, you will have to execute the following steps:

    1.  $ cd ..

    2.  $ vi ext/hello_cy/config.m4

    3.  $ ./buildconf

    4.  $ ./configure --[with|enable]-hello_cy

    5.  $ make

    6.  $ ./php -f ext/hello_cy/hello_cy.php

    7.  $ vi ext/hello_cy/hello_cy.c

    8.  $ make

    Repeat steps 3-6 until you are satisfied with ext/hello_cy/config.m4 and

    step 6 confirms that your module is compiled into PHP. Then, start writing

    code and repeat the last two steps as often as necessary.

    5、将生成的空模块mv到自己的目录下去(这里我们没有按照上面ext_skel的说明来做)

    [chengyi@localhost ext]$ mv hello_cy/ ~/test-all/php-extension/ 

    6、进入到空模块下,查看都生成了哪些文件

    [chengyi@localhost hello_cy]$ ls -p

    config.m4  config.w32  CREDITS  EXPERIMENTAL  hello_cy.c  hello_cy.php  php_hello_cy.h  tests/

    可以看到,有一个tests目录。

    7、修改config.m4文件,打开编译选项

    PHP_ARG_ENABLE(hello_cy, whether to enable hello_cy support,

    [  --enable-hello_cy           Enable hello_cy support])

    if test "$PHP_HELLO_CY" != "no"; then

    AC_DEFINE(HAVE_HELLO_CY, 1, [Whether you have Hello World])

    PHP_NEW_EXTENSION(hello_cy, hello_cy.c, $ext_shared)

    fi

    8、执行phpize生成更多文件,为编译做准备

    [chengyi@localhost hello_cy]$ phpize 

    Configuring for:

    PHP Api Version:         20041225

    Zend Module Api No:      20060613

    Zend Extension Api No:   220060519

    [chengyi@localhost hello_cy]$ ls

    acinclude.m4    build         config.m4   configure.in  EXPERIMENTAL  install-sh       missing         run-tests.php

    aclocal.m4      config.guess  config.sub  config.w32    hello_cy.c    ltmain.sh        mkinstalldirs   tests

    autom4te.cache  config.h.in   configure   CREDITS       hello_cy.php  Makefile.global  php_hello_cy.h

    9、开始编译

    ./configure --enable-hello_cy

    make

    make test

    sudo make install (有时php ext路径不对,就手工cp过去)

    10、测试

    [chengyi@localhost hello_cy]$ php hello_cy.php 

    Functions available in the test extension:

    confirm_hello_cy_compiled

    self_concat

    Congratulations! You have successfully modified ext/hello_cy/config.m4. Module hello_cy is now compiled into PHP.

    11、如果想要重新获取到一个干净的目录,执行 phpize --clean

    12、将扩展加载,修改php.ini文件

    如果不确定php.ini的位置,执行如下:

    [chengyi@localhost hello_cy]$ php -i|grep "php.ini"

    Configuration File (php.ini) Path => /usr/local/php/lib

    Loaded Configuration File => /usr/local/php/lib/php.ini

    可以看到,该文件在/usr/local/php/lib/php.ini。

    在该文件中添加: extension=hello_cy.so

    然后重启apache,如果需要在web端执行的话(如果仅在本地脚本执行,则不用重启apache,因为压根没关系)。

    -----------------------------------------------------

    探求代码为什么这么写呢?

    首先要声明,探求这些只能去PHP的源码看了。源码中比较重要的两个目录是main和Zend。

    1、PHP_FUNCTION(self_concat){} 是个什么东西?为什么要用它来定义我们的函数呢?

    我们在里面找寻PHP_FUNCTION的定义,在main/下:

    php.h:#define PHP_FUNCTION                      ZEND_FUNCTION

    然后我们去Zend/目录下,发现了 ZEND_FUNCTION的定义:

    zend_API.h:#define ZEND_FUNCTION(name)                          ZEND_NAMED_FUNCTION(ZEND_FN(name))

    然后继续由 ZEND_NAMED_FUNCTION, ZEND_FN的定义追查下去得到: void zif_name(INTERNAL_FUNCTION_PARAMETERS)

    再看INTERNAL_FUNCTION_PARAMETERS (其实php源码下都有tags,直接ctrl+]就可以跟踪定义了),得到完整的函数定义:

    void zif_name(int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_value_used TSRMLS_DC); // 其实我还蛮好奇这几个参数为什么要这样设置的,等有空去仔细看源码

    2、怎样返回值?

    我们经常使用的返回值的宏是 RETURN_STRING之类的,去Zend/下找它的定义:

    #define RETURN_STRING(s, duplicate)     { RETVAL_STRING(s, duplicate); return; }

    #define RETVAL_STRING(s, duplicate)         ZVAL_STRING(return_value, s, duplicate)

    可以看出,是给函数定义的参数return_value赋值了,然后估计是由PHP内部的机制,直接把return_value返回。

  • 相关阅读:
    openstack私有云布署实践【7.2 keystone + memcache (办公网环境)】
    openstack私有云布署实践【2 安装前的服务器基本环境准备】
    openstack私有云布署实践【11.1 计算nova compute节点配置(科兴环境)】
    openstack私有云布署实践【4.2 上层代理haproxy+nginx配置 (办公网测试环境)】
    openstack私有云布署实践【9.1 Glance镜像管理(科兴环境)】
    openstack私有云布署实践【7.1 keystone + memcache (科兴环境)】
    openstack私有云布署实践【10.1 计算nova kxcontroller节点配置(科兴环境)】
    openstack私有云布署实践【6 RabbitMQ】
    openstack私有云布署实践【4.1 上层代理haproxy配置 (科兴环境)】
    openstack私有云布署实践【8.2 身份认证keystone的API创建(办公网环境)】
  • 原文地址:https://www.cnblogs.com/wudan7/p/4183219.html
Copyright © 2020-2023  润新知