由于本人在刚开始接触PHP扩展开发的时候,在网上了很多各种各样的参考文章,但文章的内容感觉并没十分大的帮助,于是结合自已的经验写了本文。
本文介绍了怎样使用C++来开发PHP的相关扩展,本文的开发环境为:Linux5 、PHP5.4。本人只能该环境进行了测试,对于其他版本是否适用本人不得而知,请各位谅解。
文章开始前先说明下,本文的所有内容都是在前一个例子 "使用C++ 开发PHP扩展" 的前提下完成的,因为上一文是本文开发的前提。
同时本文开发还使用到了 NetBeans C++开发工具
用C++扩展PHP 的文章在百度空间及QQ空间中有发表。
百度的地址:
文章一 (使用C++ 开发PHP扩展):hi.baidu/laisl/blog/item/f4eefe17271e8329c93d6dcd.html?timeStamp=1338269348402
文章二 (C++类 PHP开发示例):hi.baidu/laisl/blog/item/c462074e76c471ead0c86a00.html
QQ空间地址:
文章一 (使用C++ 开发PHP扩展):user.qzone.qq/185287676/infocenter#!app=2&pos=1337760036
文章二 (C++类 PHP开发示例):user.qzone.qq/185287676/infocenter#!app=2&pos=1338276651
接上文:
1、在NetBeans中新建一个C++项目,我的项目名称取名为 myfunctions
2、在PHP5.4中生成一个扩展 ./ext_skel --extname=myfunctions
3、将PHP5.4源码目录下的myfunctions(ext/myfunctions)目录中的全部文件复制到 myfunctions的C++项目中来
4、在C++项目中打开 config.m4 文件并做相应修改,修改方法请参照 "使用C++ 开发PHP扩展"
5、在NetBeans 中新建一个类 MyClass,会自动生成 MyClass.cpp、MyClass.h 两个文件
6、在MyClass.h 文件中写入内容(其实这里面的内容也就是C++的类定义的东西,你懂的),内容如下:
#ifndef MYCLASS_H
#define MYCLASS_H
#include<string>          // 因为要对字符串进行操作,所以要把 string.h 包含进来
using namespace std;
class MyClass {
public:
MyClass(char *s="default");  // 构造方法
~MyClass();    // 析构函数
char* getString();  // 获取字符串函数
void setString(char *s);  // 给字符串赋值函数
private:
char *itsString;  // 成员变量
};
#endif
7、在MyClass.cpp 文件中写入相关内容(其实这里面的内容也就是C++的类定义的东西,你懂的),内容如下:
#include "MyClass.h"      // 包含头文件进来
MyClass::MyClass(char *s) {// 构造方法
itsString = s;
}
MyClass::~MyClass() {// 析构方法
}
char* MyClass::getString(){// 获取字符串内容
目前行的php开发工具有
return itsString;
}
void MyClass::setString(char *s){// 设置字符串内容
itsString = s;
}
8、在 config.m4 文件中将 MyClass.cpp 文件包含进去,config.m4 文件修改后的内容如下:
PHP_ARG_ENABLE(myfunctions, whether to enable myfunctions support,
[  --enable-myfunction
s          Enable myfunctions support])
if test "$PHP_MYFUNCTIONS" != "no"; then
PHP_REQUIRE_CXX()
dnl  PHP_SUBST(MYFUNCTIONS_SHARED_LIBADD)  此句可有可无,不知道起什么作用
PHP_ADD_LIBRARY(stdc++, "", EXTRA_LDFLAGS)
PHP_NEW_EXTENSION(myfunctions, myfunctions.cpp MyClass.cpp, $ext_shared)
fi
9、修改 php_myfunctions.h 文件,修改方法请参照 "使用C++ 开发PHP扩展"
10、修改 myfunction.cpp 文件,这个文件的修改跟之前的示例修改相似,但增加了相关内容,具体修改如下:
a、用 extern "C" 用大括号将以下行括起来
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
b、在 extern "C" 的大括号外添加这句: #include "MyClass.h"  就是将自已定义的类头文件包含进来
c、修改 ZEND_GET_MODULE(myfunctions),修改后:
BEGIN_EXTERN_C()
ZEND_GET_MODULE(myfunctions)
END_EXTERN_C()
d、到 const zend_function_entry myfunctions_functions[],在其里面添加如下内容:
PHP_ME(MyClass,__construct,NULL,ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
PHP_ME(MyClass,getString,NULL,ZEND_ACC_PUBLIC)
PHP_ME(MyClass,setString,NULL,ZEND_ACC_PUBLIC)
f、到 PHP_MINIT_FUNCTION(myfunctions) 对其里面的内容进行修改,修改后如下所示:
zend_class_entry ce;
INIT_CLASS_ENTRY(ce,"MyClass",myfunctions_functions);
myclass_ce = zend_register_internal_class(&ce TSRMLS_CC);
myclass_ce->create_object = myclass_create_handler;// 之前忘记了这一句,导致不能只实例化不使用。切记别忘记呀(创建句柄)
memcpy(&myclass_object_handlers,zend_get_std_object_handlers(),sizeof(zend_object_handlers));
myclass_object_handlers.clone_obj = NULL;
return SUCCESS;
g、添加以下内容,以便将C++的类及方法映射到PHP中来。内容可以直接到到 #include的下面或其他地方也可以
// 声明一个 php 引擎 引用的句柄及入口变量
zend_object_handlers myclass_object_handlers;// 声明一个句柄
zend_class_entry *myclass_ce;// 声明一个入口
// 声明一个结构体,主要用来存储及访问C++中的类和方法
struct myclass_object{
zend_object std;
MyClass *myclass;
};
// 释放C++使用的资源,就是自定义一个自已的方法来释放C++占用的资源
void myclass_free_storage(void *object TSRMLS_DC){
myclass_object *o = (myclass_object *)object;
delete o->myclass;
zend_hash_destroy(o->std.properties);
FREE_HASHTABLE(o->std.properties);
efree(o);
}
// 创建一个C++句柄,就是自定义一个方法来创建C++的引用句柄
zend_object_value myclass_create_handler(zend_class_entry *type TSRMLS_DC){
zval *tmp;
zend_object_value retval;
myclass_object *object = (myclass_object *)emalloc(sizeof(myclass_object));
memset(object,0,sizeof(
myclass_object));
object-& = type;
ALLOC_HASHTABLE(object->std.properties);
zend_hash_init(object->std.properties,0,NULL,ZVAL_PTR_DTOR,0);
zend_hash_copy(object->std.properties,&type->function_table,(copy_ctor_func_t)zval_add_ref, (void*)&tmp,sizeof(zval*));// 此处我看网上很多资料是 &type->default_properties,其实这个是根据你PHP的版本来定,可以查看PHP源码 zend.件查看zend_class_entry结构体的定义
retval.handle = zend_objects_store_put(object,NULL,myclass_free_storage,NULL TSRMLS_CC);
retval.handlers = &myclass_object_handlers;
return retval;
}
// 将C++对应的方法映射过来
PHP_METHOD(MyClass,__construct){// 映射C++中的构造函数
char *arg;
int len;
MyClass *myclass = NULL;
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,"s",&arg,&len)==FAILURE){
RETURN_NULL();
}
//php_printf("__construct");
myclass = new MyClass(arg);
myclass->setString(arg);
myclass_object *object = (myclass_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
object->myclass = myclass;
}
PHP_METHOD(MyClass,getString){// 映射C++中的getString函数
MyClass *myclass;
myclass_object *object = (myclass_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
myclass = object->myclass;
char *aa;
if(myclass != NULL){
aa = myclass->getString();
//php_printf(" getString: %s",aa);
RETURN_STRING(aa,0);
}
RETURN_NULL();
}
PHP_METHOD(MyClass,setString){// 映射C++中的setString函数
char *arg;
int len;
MyClass *myclass = NULL;
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,"s",&arg,&len)==FAILURE){
RETURN_NULL();
}
//php_printf(" set string is : %s",arg);
myclass = new MyClass(arg);
myclass->setString(arg);
myclass_object *object = (myclass_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
object->myclass = myclass;
}
11、使用你的 phpize 工具来生成配置项
① cd myfunctions
② 执行 /usr/local/php5/bin/phpize    注意PHP安装的路径
12、执行 ./configure --with-php-config=/usr/local/php5/bin/php-config      注意后面你PHP的安装路径
13、执行 make && make install
14、在php.ini配置文件中添加 extension=myfunctions.so
15、重启 apache 服务器
16、测试是否成功
新建一个PHP文件输入:
<?php
$my = new MyClass("suilin");
echo $my->getString();// 输出:suilin  正确
到此使用 C++ 开发PHP扩展课程内容结束,更多的扩展应用请结合自已的实际来开发。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。