php写扩展

用PHP扩展做一个HelloWorld!

PHP 尽管提供了大量有用的函数,但是在特殊情况下还可能需要进行扩展编程,比如大量的 PECL(PHP Extension Community Library)就是以扩展的形式提供的(动态链接库dll文件),它们比 PEAR 的运行效率要高很多。
    PHP 扩展是用 C 或 C++ 编写的,需要编译成动态连接库 dll 文件后在 PHP 环境下注册后才能使用。
    编写 PHP 扩展的软件要求:
      VC++6.0 或 VC++.NET 环境。
      PHP 的源代码,需要编译。
    如果不愿意编译 PHP 的源代码,可以再下载 PHP 的已经编译成功的二进制代码(就是我们部署 PHP 运行环境的那些文件包)。注意分别下载的源文件包和已编译包,它们的版本必须一致。

过程:

1,安装 VC++6.0,并选择把其可执行文件路径加入环境变量中,使在命令行环境任意路径下可以运行编译器。
    2,安装 PHP 运行环境,并与 IIS 正确集成在一起。假设使用的 PHP 版本为 5.2.5,下载 php-5.2.5-Win32.zip 二进制包和 php-5.2.5.tar.gz 源代码包。安装环境为 C:\php-5.2.5-Win32。分别把源代码包和二进制包解压到该文件夹下。从 php.ini-recommended 拷贝生成一个 php.ini 文件。
    3,建立 C:\php-5.2.5-Win32\Release_TS 文件夹,拷贝 C:\php-5.2.5-Win32\dev\php5ts.lib 文件到这里。
    4,进入 C:\php-5.2.5-Win32\ext 文件夹,运行命令:
      C:\php-5.2.5-Win32\ext>..\php.exe ext_skel_win32.php --extname=myphpext
      Creating directory myphpext
      Creating basic files: config.m4 config.w32 .cvsignore myphpext.c php_myphpext.h
      CREDITS EXPERIMENTAL tests/001.phpt myphpext.php [done].

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

1.  $ cd ..
      2.  $ vi ext/myphpext/config.m4
      3.  $ ./buildconf
      4.  $ ./configure --[with|enable]-myphpext
      5.  $ make
      6.  $ ./php -f ext/myphpext/myphpext.php
      7.  $ vi ext/myphpext/myphpext.c
      8.  $ make

Repeat steps 3-6 until you are satisfied with ext/myphpext/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.

结果在 ext 下生成一个文件夹 myphpext,包含一个 PHP 扩展应用编程框架。myphpext 可以任意取名,将来生成的 dll 文件格式为 php_[extname].dll,我们生成的就是 php_myphpext.dll。运行结果的提示信息 1.2...8 主要是对 Linux/Unix 环境而言的,我们不必理会。其实 config.m4 文件在 Windows 下也可能需要修改,但是对于我们简单的框架暂时还用不着。

文件夹 myphpext 包含若干个文件,其中:

myphpext.dsp 是工程文件,后边还要用;
    myphpext.php 扩展测试文件;
    php_myphpext.h 扩展函数定义头文件
    myphpext.c 扩展函数具体实现

以上 2 个重要的文件内容:

php_myphpext.h 文件:

/*
      +----------------------------------------------------------------------+
      | PHP Version 5                                                        |
      +----------------------------------------------------------------------+
      | Copyright (c) 1997-2007 The PHP Group                                |
      +----------------------------------------------------------------------+
      | This source file is subject to version 3.01 of the PHP license,      |
      | that is bundled with this package in the file LICENSE, and is        |
      | available through the world-wide-web at the following url:           |
      | http://www.php.net/license/3_01.txt                                  |
      | If you did not receive a copy of the PHP license and are unable to   |
      | obtain it through the world-wide-web, please send a note to          |
      | [email protected] so we can mail you a copy immediately.               |
      +----------------------------------------------------------------------+
      | Author:                                                              |
      +----------------------------------------------------------------------+
    */

    /* $Id: header,v 1.16.2.1.2.1 2007/01/01 19:32:09 iliaa Exp $ */

    #ifndef PHP_MYPHPEXT_H
    #define PHP_MYPHPEXT_H

    extern zend_module_entry myphpext_module_entry;
    #define phpext_myphpext_ptr &myphpext_module_entry

    #ifdef PHP_WIN32
    #define PHP_MYPHPEXT_API __declspec(dllexport)
    #else
    #define PHP_MYPHPEXT_API
    #endif

    #ifdef ZTS
    #include "TSRM.h"
    #endif

    PHP_MINIT_FUNCTION(myphpext);
    PHP_MSHUTDOWN_FUNCTION(myphpext);
    PHP_RINIT_FUNCTION(myphpext);
    PHP_RSHUTDOWN_FUNCTION(myphpext);
    PHP_MINFO_FUNCTION(myphpext);

    PHP_FUNCTION(confirm_myphpext_compiled); /* For testing, remove later. */
    PHP_FUNCTION(HelloPHP);

    /*
       Declare any global variables you may need between the BEGIN
     and END macros here:

    ZEND_BEGIN_MODULE_GLOBALS(myphpext)
     long  global_value;
     char *global_string;
    ZEND_END_MODULE_GLOBALS(myphpext)
    */

    /* In every utility function you add that needs to use variables
       in php_myphpext_globals, call TSRMLS_FETCH(); after declaring other
       variables used by that function, or better yet, pass in TSRMLS_CC
       after the last function argument and declare your utility function
       with TSRMLS_DC after the last declared argument.  Always refer to
       the globals in your function as MYPHPEXT_G(variable).  You are
       encouraged to rename these macros something shorter, see
       examples in any other php module directory.
    */

    #ifdef ZTS
    #define MYPHPEXT_G(v) TSRMG(myphpext_globals_id, zend_myphpext_globals *, v)
    #else
    #define MYPHPEXT_G(v) (myphpext_globals.v)
    #endif

    #endif /* PHP_MYPHPEXT_H */

    /*
     * Local variables:
     * tab-width: 4
     * c-basic-offset: 4
     * End:
     * vim600: noet sw=4 ts=4 fdm=marker
     * vim<600: noet sw=4 ts=4
     */

myphpext.c 文件:

/*
      +----------------------------------------------------------------------+
      | PHP Version 5                                                        |
      +----------------------------------------------------------------------+
      | Copyright (c) 1997-2007 The PHP Group                                |
      +----------------------------------------------------------------------+
      | This source file is subject to version 3.01 of the PHP license,      |
      | that is bundled with this package in the file LICENSE, and is        |
      | available through the world-wide-web at the following url:           |
      | http://www.php.net/license/3_01.txt                                  |
      | If you did not receive a copy of the PHP license and are unable to   |
      | obtain it through the world-wide-web, please send a note to          |
      | [email protected] so we can mail you a copy immediately.               |
      +----------------------------------------------------------------------+
      | Author:                                                              |
      +----------------------------------------------------------------------+
    */

    /* $Id: header,v 1.16.2.1.2.1 2007/01/01 19:32:09 iliaa Exp $ */

    #ifdef HAVE_CONFIG_H
    #include "config.h"
    #endif

    #include "php.h"
    #include "php_ini.h"
    #include "ext/standard/info.h"
    #include "php_myphpext.h"

    /* If you declare any globals in php_myphpext.h uncomment this:
    ZEND_DECLARE_MODULE_GLOBALS(myphpext)
    */

    /* True global resources - no need for thread safety here */
    static int le_myphpext;

    /* {{{ myphpext_functions[]
     *
     * Every user visible function must have an entry in myphpext_functions[].
     */
    zend_function_entry myphpext_functions[] = {
     PHP_FE(confirm_myphpext_compiled, NULL)  /* For testing, remove later. */
     PHP_FE(HelloPHP, NULL)
     {NULL, NULL, NULL} /* Must be the last line in myphpext_functions[] */
    };
    /* }}} */

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

    #ifdef COMPILE_DL_MYPHPEXT
    ZEND_GET_MODULE(myphpext)
    #endif

    /* {{{ PHP_INI
     */
    /* Remove comments and fill if you need to have entries in php.ini
    PHP_INI_BEGIN()
        STD_PHP_INI_ENTRY("myphpext.global_value",      "42", PHP_INI_ALL, OnUpdateLong, global_value, zend_myphpext_globals, myphpext_globals)
        STD_PHP_INI_ENTRY("myphpext.global_string", "foobar", PHP_INI_ALL, OnUpdateString, global_string, zend_myphpext_globals, myphpext_globals)
    PHP_INI_END()
    */
    /* }}} */

    /* {{{ php_myphpext_init_globals
     */
    /* Uncomment this function if you have INI entries
    static void php_myphpext_init_globals(zend_myphpext_globals *myphpext_globals)
    {
     myphpext_globals->global_value = 0;
     myphpext_globals->global_string = NULL;
    }
    */
    /* }}} */

    /* {{{ PHP_MINIT_FUNCTION
     */
    PHP_MINIT_FUNCTION(myphpext)
    {
     /* If you have INI entries, uncomment these lines
     REGISTER_INI_ENTRIES();
     */
     return SUCCESS;
    }
    /* }}} */

    /* {{{ PHP_MSHUTDOWN_FUNCTION
     */
    PHP_MSHUTDOWN_FUNCTION(myphpext)
    {
     /* uncomment this line if you have INI entries
     UNREGISTER_INI_ENTRIES();
     */
     return SUCCESS;
    }
    /* }}} */

    /* Remove if there‘s nothing to do at request start */
    /* {{{ PHP_RINIT_FUNCTION
     */
    PHP_RINIT_FUNCTION(myphpext)
    {
     return SUCCESS;
    }
    /* }}} */

    /* Remove if there‘s nothing to do at request end */
    /* {{{ PHP_RSHUTDOWN_FUNCTION
     */
    PHP_RSHUTDOWN_FUNCTION(myphpext)
    {
     return SUCCESS;
    }
    /* }}} */

    /* {{{ PHP_MINFO_FUNCTION
     */
    PHP_MINFO_FUNCTION(myphpext)
    {
     php_info_print_table_start();
     php_info_print_table_header(2, "myphpext support", "enabled");
     php_info_print_table_end();

     /* Remove comments if you have entries in php.ini
     DISPLAY_INI_ENTRIES();
     */
    }
    /* }}} */

    /* Remove the following function when you have succesfully modified config.m4
       so that your module can be compiled into PHP, it exists only for testing
       purposes. */

    /* Every user-visible function in PHP should document itself in the source */
    /* {{{ proto string confirm_myphpext_compiled(string arg)
       Return a string to confirm that the module is compiled in */
    PHP_FUNCTION(confirm_myphpext_compiled)
    {
     char *arg = NULL;
     int arg_len, len;
     char *strg;

     if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {
      return;
     }

     len = spprintf(&strg, 0, "Congratulations! You have successfully modified ext/%.78s/config.m4. Module %.78s is now compiled into PHP.", "myphpext", arg);
     RETURN_STRINGL(strg, len, 0);
    }

    PHP_FUNCTION(HelloPHP)
    {
     php_printf("Hello, PHP v5.2.5 - 2008-3-28");
    }

    /* }}} */
    /* The previous line is meant for vim and emacs, so it can correctly fold and
       unfold functions in source code. See the corresponding marks just before
       function definition, where the functions purpose is also documented. Please
       follow this convention for the convenience of others editing your code.
    */

    /*
     * Local variables:
     * tab-width: 4
     * c-basic-offset: 4
     * End:
     * vim600: noet sw=4 ts=4 fdm=marker
     * vim<600: noet sw=4 ts=4
     */

注意本例定义了一个函数 HelloPHP。在 php_myphpext.h 文件中定义:
    PHP_FUNCTION(HelloPHP);

在 myphpext.c 中有 2 处地方:

PHP_FE(HelloPHP, NULL) 语句把我们自己的函数加入入口数组中。

以下定义了 HelloPHP 函数的内容:
    PHP_FUNCTION(HelloPHP)
    {
     php_printf("Hello, PHP v5.2.5 - 2008-3-28");
    }

其实还有个 confirm_myphpext_compiled 函数,是自动产生的,用于测试,与我们的自定义函数用法一模一样。

5,编译、链接,生成最终的文件。

C:\php-5.2.5-Win32\ext>msdev myphpext\myphpext.dsp /MAKE "myphpext - Win32 Release_TS"
    -----------Configuration: myphpext - Win32 Release_TS-----------
    Compiling...
    myphpext.c
    Linking...
       Creating library Release_TS/php_myphpext.lib and object Release_TS/php_myphpext.exp

php_myphpext.dll - 0 error(s), 0 warning(s)

最终在 C:\php-5.2.5-Win32\Release_TS 下生成了扩展库 php_myphpext.dll。

6,部署:

把 php_myphpext.dll 拷贝到 C:\php-5.2.5-Win32\ext 文件夹下。修改 php.ini 文件:

加语句 extension=php_myphpext.dll。

再注意 extension 路径的指向,需要把 ;extension_dir = "./" 语句的注释去掉,再修改为 extension_dir = "C:\php-5.2.5-Win32\ext"。

最后一定要重启 IIS 服务器。

7,测试:

把 myphpext.php 拷贝到 Web 服务器根下(myphpext.php 的代码也值得一看),在本机用浏览器打开:http://localhost/myphpext.php,应该能看到以下信息:

Functions available in the test extension:
    confirm_myphpext_compiled
    HelloPHP

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

再建立一个 test.php 文件,内容为:

   <?php
      HelloPHP();
    ?>

时间: 2024-10-06 23:56:44

php写扩展的相关文章

使用Cython为Python写扩展1:初识Cython

使用Cython为Python写扩展1:初识Cython Cython使为Python写C扩展就如同写Python代码一样简单.广泛用于数学软件包,SAGE公司,作为执行快速,可扩展的运算.它提供了安全和可维护的方法通过自动生成所需代码来构建原生Python模块. 我们经常会使用Cython将C/C++实现的系统绑定到Python中,这样我们就可以使用Python来处理高级别逻辑,原生模块来处理底层代码. 关于示例 代码 http://git.oschina.net/erhuabushuo/le

CAD在网页中绘图,并为新绘的对象写扩展数据和读取扩展数据

在网页中绘图,并为新绘的对象写扩展数据和读取扩展数据.下面帮助的完整例子,在控件安装目录的 Sample\Ie\iedemo.htm 中. 主要用到函数说明: _DMxDrawX::InsertBlock 向数据库中插入一个图块,DWG图块文件可以是本地文件,也可以是网络文件.详细说明如下:函数成功返回1,失败返回0. 参数 说明 BSTR pszDwgFileName 图块定义的dwg 文件,支持http://开头的网络路径 BSTR pszBlockName 新插入的图块名 _DMxDraw

自写扩展方法

有时候我们需要一个方法,但是.net没有提供,我们需要自己写个扩展方法 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace CsTest 8 { 9 static class kuozhan 10 { 11 public static string se(this str

记一次自写php扩展的安装

环境: centos 6.5 php7.0 gcc 4.9 cmake 3.5.2 艰辛的过程 简单介绍一下这个扩展,这个扩展是基于phpx的架构编写的,稍微修改过源码.p.s.由于源码的编写并没有怎么参与,此处只介绍安装过程中的坑. 首先,由于环境不一致,开发的时候使用centos7,安装的时候在6.5,很多工具的版本对不上,于是,需要各种升级. 1.gcc的升级 # 卸载gccyum remove gcc wget http://gcc.skazkaforyou.com/releases/g

随手写的一个对DataRow和DataSqlReader的扩展方法

因为觉得一般使用DataRow获取行数据时使用字符串 会有太多的不确定和类型判断所以想自己扩展一下 最后成果 public class Model { public int objUserID { get; set; } public string FirstName { get; set; } } class Program { static void Main(string[] args) { DataRow r = null; var contact= r.GetContact<Model

C#中的扩展方法

在java中没有这样的东西,一个类一旦是 final的 ,这个类就不能再被添加方法, 但是C#能够做到,可以给 sealed 类添加新的方法,这点我还是比较喜欢c#的. 这就是C#中的扩展方法. 那么什么情况下我们才需要去给一个类写扩展方法呢? 系统自带的类型,我们无法去修改: 修改源代码需要较大的精力,而且可能会带来错误: 我们只是需要一个或者较少的几个方法,修改源代码费时费力: 被扩展的类是sealed的,不能被继承:(就算不是sealed的,我们也不能因为需要一个方法而去写一个子类,这样不

22 扩展Python - 《Python 核心编程》

?? 引言/动机 ?? 扩展 Python ?? 创建应用程序代码 ?? 用样板包装你的代码 ?? 编译 ?? 导入并测试 ?? 引用计数 ?? 线程和 GIL ?? 相关话题 22.1 介绍/动机 什么是扩展 一般来说,所有能被整合或导入到其它python 脚本的代码,都可以被称为扩展.您可以用纯 Python 来写扩展,也可以用C 和C++之类的编译型的语言来写扩展(或者也可以用Java 给Jython 写 扩展,也可以用C#或Visual Basic.NET 给IronPython 写扩展

PHP开发第一个扩展

首先声明:我们要构建的是扩展或者模块名为hello_module.该模块提供一个方法:hello_word. 一.PHP环境的搭建 1)一般使用源码包编译安装,而不是binary包安装.因为使用PHP的二进制分发包安装有些冒险,这些版本倾向于忽略./configure的两个重要选项,它们在开发过程中很便利: 第一个--enable-debug.这个选项将把附加的符号信息编译进PHP的执行文件,以便如果发生段错误,你能从中得到一个内核转储文件,使用gdb追踪并发现什么地方以及为什么会发生段错误.

JavaScript学习总结(十四)——JavaScript编写类的扩展方法

在?J?a?v?a?S?c?r?i?p?t?中?可以使?用?类的p?r?o?t?o?t?y?p?e属性来?扩?展?类的属?性?和?方?法,在实际开发当中,当JavaScript内置的那些类所提供的动态方法和动态属性不满足我们实际开发时,我们就可以通过"prototype"属性给自定义类添加方法和属性或者扩展原有的类中的方法和属性. 一.扩展JavaScript内置类,添加动态方法 语法格式: 类名.prototype.方法名 = function([param1],[param2],.