1. 程式人生 > >Windows下的PHP擴充套件程式設計

Windows下的PHP擴充套件程式設計

    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();
    ?>

    用本機瀏覽器開啟:http://localhost/test.php,應該能看到以下資訊:

    Hello, PHP v5.2.5 - 2008-3-28

    這說明我們所有的步驟都是正確的,已經生成了一個自己的 PHP 擴充套件函式庫。只要對 C 語言熟悉,就可以編寫大量的自定義函式,供所有人呼叫。注意,不像 PEAR 等函式庫,需要首先在 PHP 程式碼裡指定其檔名才能使用其中的函式和類。PHP 擴充套件的函式不是用 PHP 語言自身開發的,而是 C 開發的,而且可以直接在 PHP 程式碼裡呼叫。這樣既有一定的保密性,還有效率上的優勢。
    開發 PHP 擴充套件的更多示例可以參考 PHP 的原始碼,或者其它的 PECL 原始碼。從那裡可以學習到大量的技巧。

相關推薦

Windowsphp擴充套件開發c++動態庫

PHP擴充套件開發,從零瞭解到初步完成一個小專案,經過三天的仔細研究,現整理如下 一、需求介紹 PHP擴充套件開發,呼叫自己之前的c++動態庫,完成功能 二、專案之前 系統:windows xp  開發工具:vs 2008 web環境:apache2.4  PHP5.3.2

WindowsPHP擴充套件資源列表及下載地址(官方)

官方下載的php安裝包ext目錄裡以經包含了常用的php擴充套件,但某些情況下並不能滿足我們專案需求,比如memcache擴充套件就不在官方的php安裝包裡。這時就需要我們自己去下載安裝。 本文列出php官方提供的php擴充套件下載地址,及所有的擴充套件列表。 PHP

WindowsPHP擴充套件程式設計

    PHP 儘管提供了大量有用的函式,但是在特殊情況下還可能需要進行擴充套件程式設計,比如大量的 PECL(PHP Extension Community Library)就是以擴充套件的形式提供的(動態連結庫dll檔案),它們比 PEAR 的執行效率要高很多。    P

windows php安裝redis擴充套件

下載網站連結https://pecl.php.net/package/redis 1.下載php_redis.dll,下載地址https://pecl.php.net/package/redis 2.找到php安裝目錄將下載的包裡面的這兩個檔案放到ext資料夾裡 php_redis.dll

WindowsPHP安裝 Imagick 擴充套件

最近的PHP專案中,需要用到切圖和縮圖的效果,在本地windows開發環境,安裝過程遇到好多問題,在此與大家分享。php官網裡,一大群老外也看不懂這玩意怎麼裝,主要原因在於,php版本龐雜,還有x86 x64 nts ts,對應的imagick版本也不一定相同,imagick

WindowsPHP多執行緒擴充套件pthreads的安裝

檢視phpinfo() 複製檔案 複製php_pthreads.dll到D:\wamp\bin\php\php5.5.12\ext\目錄下 複製pthreadVC2.dll到D:\wamp

windowsPHP的oci和pdo_oci擴充套件安裝

配置環境: - windows7 - PHP Version 5.6.19 - Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 安裝oci擴充套件 Configur

windowsphp、mysql環境搭建

ins ads unity 5.7 文件 all color 註意 ont php http://windows.php.net/download/ mysql https://dev.mysql.com/downloads/windows/installer/5.7.ht

windowsphp配置redis

修改 src nload php red html nec ads art 方法/步驟 1.使用phpinfo()函數查看PHP的版本信息,這會決定擴展文件版本 2.根據PHP版本號,編譯器版本號和CPU架構, 選擇php_redis-2.2.5-5.5-

WindowsPHP安全環境的搭建

版本 right AC info 所有 lock 六月 .com ash 筆者一直在Windows環境下搭建PHP的運行環境,大大小小的運行環境用過不少,從開始的WAMP到後來的XAMPP以及PHPnow。WAMP和XAMPP都是繼承mysql apache以及PHP庫的運

windows php 配置redis oracle

ins 配置 oracl nload ron 環境 conn oracle client 下載擴展地址: 1、https://windows.php.net/downloads/pecl/releases/redis 2、https://pecl.php.net/packa

windowsPHP + Nginx curl訪問本地超時(wamp環境curl訪問本地超時)

以下是自己的一些理解: wamp環境下nginx並不是真正的伺服器,nginx只是起到了代理的作用,真正的伺服器是php-cgi。我們在配置wamp環境的時候都會指定fastcgi_pass 為 127.0.0.1:9000。而這種情況是不支援併發的,也就是說伺服器處理完上個請求才能處理下個請求

windows php-cgi.exe 0xc000007b 錯誤 阿星小棧

    dll缺失可以用 DirectX9 去修復。不限於64,32。  0xc000007b 報錯: php5.3、5.4和apache都是用vc9編譯,電腦必須安裝vc9執行庫才能執行。 php5.5、5.6是vc11編譯,如用php

windows的網路程式設計實現

下面是一個簡單的windows下的服務端和客戶端的實現程式碼需要注意的是 1、此程式設計實現的只是最簡單的網路通訊,不支援多程序和多執行緒的併發(網上找到很多過於多程序和多執行緒併發的伺服器端設計,不過都是在linux下的,在windows下的建立程序和執行緒的函式不熟悉,也沒怎麼看懂,

PHP整合環境一鍵安裝】Windowsphp整合環境一鍵安裝教程

 目標:讓天下沒有難配的php環境。 該程式包整合 Apache+Nginx+LightTPD+PHP+MySQL+phpMyAdmin+Zend Optimizer+Zend Loader,一次性安裝,無須配置即可使用,是非常方便、好用的PHP除錯環境。該程式綠色小巧簡

windowsPHP獲取視訊第一幀圖片作為背景圖

我在網上找了很多這方面的資料,總結如下:一般用ffmpeg獲取視訊第一幀圖片作為背景圖; ffmpeg的下載連結  http://ffmpeg.org/download.html ; 下載好包,包裡面在

windowsphp mongodb 安裝配置使用查詢

這幾天參加了一個創意馬拉松大賽,雖然沒拿什麼獎,重在參與嘛 終於有機會實踐mongodb資料庫了,以前只是自己配置裝著玩玩 作者:風來了.呆狐狸 環境:window10 64 +php5.5.x+mysql5.7.x+mongodb2.6.x mongod安裝 1.下載 h

Windows進行Socket程式設計問題

做Windows網路程式設計經常遇到下面這種情況: c:\program files\microsoft visual studio 8\vc\platformsdk\include\winsock2.h(112) : error C2011: “fd_set”: “str

Linux與Windows的網路程式設計區別

轉載:https://www.cnblogs.com/gildoringlorin/p/3951317.html socket相關程式從Windows移植到Linux下需要注意的: 1)標頭檔案  Windows下winsock.h/winsock2.h  Linux下

Windows的C++程式設計——你過時了麼?

現在很多人仍然在用VC++6.0編寫Windows下的C++程式,一些老程式設計師可能會說:“用習慣了,覺得挺好用,不需要改變”,不無道理,但事實上是跟不上編譯器以及開發環境的更新步伐。可是我們這些新生程式設計師呢——到底該如何選擇? 先讓我來陳述以下事實:    1998