程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C語言擴展PHP功能

C語言擴展PHP功能

編輯:關於C語言
 

PHP經過最近幾年的發展已經非常的流行,而且PHP也提供了各種各樣非常豐富的函數。
但有時候我們還是需要來擴展PHP。比如:我們自己開發了一個數據庫系統,而且有自己的
庫函數來操作數據庫,這時候,如果想在PHP中來操作我們自己的數據庫的話,就必須自己
擴展PHP了,像mysql,postgresql,之所以PHP能夠提供這些數據庫操作函數,也都是擴展了
PHP的結果。
先看看PHP的源代碼結構:
$ cd php-4.4.2/ext
$ ls
會顯示出目前該PHP發行版本中所有的擴展模塊。
如果想深入學習的話,可以去看看mysql或者postgresql的PHP擴展實現。

下面,我們通過一個簡單的模塊(mypg)來實現對postgresql的數據庫操作。
$ cd php-4.4.2/ext
$ ./ext_skel –extname=mypg
該程序會自動生成mypg目錄
$ cd mypg
$ ls
config.m4 CREDITS EXPERIMENTAL mypg.c mypg.php php_mypg.h tests

PHP已經自動為我們生成了一些必要的文件和示范代碼。
我們需要作一些修改才能正常的編譯和使用該mypg模塊。
$ vi config.m4
修改成如下內容:
PHP_ARG_ENABLE(mypg, whether to enable mypg support,
[ –enable-mypg Enable mypg support])

if test “$PHP_MYPG” != “no”; then
dnl Write more examples of tests here…

dnl # –with-mypg -> check with-path
dnl SEARCH_PATH=”/usr/local /usr” # you might want to change this
dnl SEARCH_FOR=”/include/mypg.h” # you most likely want to change this
dnl if test -r $PHP_MYPG/; then # path given as parameter
dnl MYPG_DIR=$PHP_MYPG
dnl else # search default path list
dnl AC_MSG_CHECKING([for mypg files in default path])
dnl for i in $SEARCH_PATH ; do
dnl if test -r $i/$SEARCH_FOR; then
dnl MYPG_DIR=$i
dnl AC_MSG_RESULT(found in $i)
dnl fi
dnl done
dnl fi
dnl
dnl if test -z “$MYPG_DIR”; then
dnl AC_MSG_RESULT([not found])
dnl AC_MSG_ERROR([Please reinstall the mypg distribution])
dnl fi

dnl # –with-mypg -> add include path
dnl PHP_ADD_INCLUDE($MYPG_DIR/include)

dnl # –with-mypg -> check for lib and symbol presence
dnl LIBNAME=mypg # you may want to change this
dnl LIBSYMBOL=mypg # you most likely want to change this

dnl PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL,
dnl [
dnl PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $MYPG_DIR/lib, MYPG_SHARED_LIBADD)
dnl AC_DEFINE(HAVE_MYPGLIB,1,[ ])
dnl ],[
dnl AC_MSG_ERROR([wrong mypg lib version or lib not found])
dnl ],[
dnl -L$MYPG_DIR/lib -lm -ldl
dnl ])
dnl
dnl PHP_SUBST(MYPG_SHARED_LIBADD)

PHP_NEW_EXTENSION(mypg, mypg.c, $ext_shared)
fi

dnl開頭的為注釋,其實我們也只是把某些注釋去掉了。

然後修改php_mypg.h,內容為:
#ifndef PHP_MYPG_H
#define PHP_MYPG_H

extern zend_module_entry mypg_module_entry;
#define phpext_mypg_ptr &mypg_module_entry

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

//模塊初始化時調用函數
PHP_MINIT_FUNCTION(mypg);

//我們的數據庫連接函數
PHP_FUNCTION(mypg_connect);
//我們的數據庫操作函數
PHP_FUNCTION(mypg_execute);
//我們的數據庫關閉函數
PHP_FUNCTION(mypg_close);

#ifdef ZTS
#include “TSRM.h”
#endif

#endif /* PHP_MYPG_H */

繼續修改mypg.c,內容改為:
#ifdef HAVE_CONFIG_H
#include “config.h”
#endif

#include “php.h”
#include “php_ini.h”
#include “ext/standard/info.h”
#include “php_mypg.h”
#include “libpq-fe.h”

int le_link;
function_entry mypg_functions[] = {
PHP_FE(mypg_connect, NULL)
PHP_FE(mypg_execute, NULL)
PHP_FE(mypg_close, NULL)
{NULL, NULL, NULL}
};
zend_module_entry mypg_module_entry = {
STANDARD_MODULE_HEADER,
“mypg”, mypg_functions, PHP_MINIT(mypg), NULL, NULL, NULL,
NULL, NO_VERSION_YET, STANDARD_MODULE_PROPERTIES
};

ZEND_GET_MODULE(mypg)

//數據庫鏈接關閉函數
static void _close_mypg_link(zend_rsrc_list_entry *rsrc TSRMLS_DC)
{
PGconn *link = (PGconn *)rsrc->ptr;
PQfinish(link);
}
PHP_MINIT_FUNCTION(mypg)
{
//注冊資源回收函數,如果沒有顯示用mypg_close關閉數據庫連接的化,PHP會自動調用該函數釋放資源
le_link = zend_register_list_destructors_ex(_close_mypg_link, NULL, “mypg link”, module_number);
return SUCCESS;

}

//連接數據庫
static void php_mypg_do_connect(INTERNAL_FUNCTION_PARAMETERS)
{
PGconn *link;

//只接受一個函數參數
if(ZEND_NUM_ARGS() != 1)
{
WRONG_PARAM_COUNT;
}

zval **connect_info;

/* get the connection information string */
if (zend_get_parameters_ex(1, &connect_info) == FAILURE) {  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved