用C实现PHP扩展类
前面简单介绍了用c语言实现php扩展的步骤,见用c开发php扩展的步骤,那个是扩展一个函数,这里讲述一下如何用c扩展类。
准备实现的类如下:
class Rectangle{
private $_width;
private $_height;
public function __construct($width, $height){
$this->_width = $width;
$this->_height = $height;
}
public function clone(){
return new Rectangle($this->_width, $this->_height);
}
public function setWidth($width){
$this->_width = $width;
}
public function setHeight($height){
$this->_height = $height;
}
public function getWidth(){
return $this->_width;
}
public function getHeight(){
return $this->_height;
}
public function getArea(){
return $this->_width * $this->_height;
}
public function getCircle(){
return ($this->_width + $this->_height) * 2;
}
}实现类扩展的步骤如下:(首先下载PHP源码,这里使用的是php-5.2.8)
1,建立扩展骨架
立即学习“PHP免费学习笔记(深入)”;
cd php-5.2.8/ext ./ext_skel --extname=class_ext
cd php-5.2.8/ext/class_ext vi config.m4
[ --enable-class_ext Enable class_ext support])两行前面的dnl,修改后为:
PHP商城系统是国内功能优秀的网上商城系统,同时也是一个商业的PHP开发框架,有多套免费模版,强大的后台管理功能,专业的网上商城系统解决方案,快速建设网上购物商城、数码商城、手机商城、办公用品商城等网站。 php商城系统v3.0 rc6升级 1、主要修复用户使用中出现的js未加载完报错问题,后台整改、以及后台栏目的全新部署、更利于用户体验。 2、扩展出,更多系统内部的功能,以便用户能够迅速找到需
0
dnl Otherwise use enable: PHP_ARG_ENABLE(class_ext, whether to enable class_ext support, dnl Make sure that the comment is aligned: [ --enable-class_ext Enable class_ext support])
cd php-5.2.8/ext/class_ext vi php_class_ext.h #在 PHP_FUNCTION(confirm_class_ext_compiled); 后面增加申明函数;
PHP_METHOD(Rectangle,__construct); PHP_METHOD(Rectangle,clone); PHP_METHOD(Rectangle,setWidth); PHP_METHOD(Rectangle,setHeight); PHP_METHOD(Rectangle,getWidth); PHP_METHOD(Rectangle,getHeight); PHP_METHOD(Rectangle,getArea); PHP_METHDO(Rectangle,getCircle);
vi class_ext.c #申明方法的参数,注册到函数表中
ZEND_BEGIN_ARG_INFO(arg_construct,2)
ZEND_ARG_INFO(0, width)
ZEND_ARG_INFO(0, height)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arg_set_width,1)
ZEND_ARG_INFO(0, width)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arg_set_height,1)
ZEND_ARG_INFO(0, height)
ZEND_END_ARG_INFO()
const zend_function_entry class_ext_functions[] = {
PHP_FE(confirm_class_ext_compiled, NULL)
PHP_ME(Rectangle, __construct, arg_construct, ZEND_ACC_CTOR|ZEND_ACC_PUBLIC)
PHP_ME(Rectangle, clone, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Rectangle, setWidth, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Rectangle, setHeight, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Rectangle, getWidth, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Rectangle, getHeight, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Rectangle, getArea, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Rectangle, getCircle, NULL, ZEND_ACC_PUBLIC)
{NULL, NULL, NULL} /* Must be the last line in class_ext_functions[] */
};#其中ZEND_ACC_CTOR表示构造函数,ZEND_ACC_PUBLIC表示访问权限为PUBLIC。
#接下来,在模块初始化函数中注册并初始化类
zend_class_entry *Rectangle_ce; //zend内部类结构变量
PHP_MINIT_FUNCTION(class_ext)
{
zend_class_entry Rectangle;
INIT_CLASS_ENTRY(Rectanble, "Rectangle", class_ext_functions); //第二个参数为类名,第三个参数为类的函数列表
Rectangle_ce = zend_register_internal_class_ex(&Rectangle, NULL, NULL TSRMLS_CC); //注册类
zend_declare_property_null(Rectangle_ce, ZEND_STRL("_width"), ZEND_ACC_PRIVATE TSRMLS_CC); //初始化类的属性_width
zend_declare_property_null(Rectangle_ce, ZEND_STRL("_height"), ZEND_ACC_PRIVATE TSRMLS_CC); //初始化类的属性_height
return SUCCESS;
}#在文件最后增加类的成员函数的具体实现代码
PHP_METHOD(Rectangle, __construct)
{
long width,height;
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &width, &height) == FAILURE){ //获取构造函数的两个函数参数_width和_height
WRONG_PARAM_COUNT;
}
if( width <= 0 ) {
width = 1; //如果_width为0,则赋默认值1
}
if( height <= 0 ) {
height = 1; //如果_height为0,则赋默认值1
}
zend_update_property_long(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("_width"), width TSRMLS_CC); //更新类成员变量_width的值
zend_update_property_long(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("_height"), height TSRMLS_CC); //更新类成员变量_height的值
RETURN_TRUE;
}
PHP_METHOD(Rectangle, clone)
{
zval *clone_obj;
zval *width,*height;
MAKE_STD_ZVAL(clone_obj);
object_init_ex(clone_obj, Rectangle_ce); //初始化对象,对象所属的类为Rectangle_ce
width = zend_read_property(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("_width"), 0 TSRMLS_CC); //获取类成员变量_width的值
height = zend_read_property(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("_height"), 0 TSRMLS_CC); //获取类成员变量_height的值
zend_update_property_long(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("_width"), width TSRMLS_CC); //更新Rectangle_ce类对象clone_obj的属性值_width
zend_update_property_long(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("_height"), height TSRMLS_CC); //更新Rectangle_ce类对象clone_obj的属性值_height
RETURN_ZVAL(clone_obj, 1, 0); //返回该对象
}
PHP_METHOD(Rectangle, setWidth()
{
long width;
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &width) == FAILURE){
WRONG_PARAM_COUNT;
}
if( width <= 0 ) {
width = 1;
}
zend_update_property_long(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("_width"), width TSRMLS_CC); //更新类成员变量_width的值
RETURN_TRUE;
}
PHP_METHOD(Rectangle, setHeight()
{
long height;
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &height) == FAILURE){
WRONG_PARAM_COUNT;
}
if( height <= 0 ) {
height = 1;
}
zend_update_property_long(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("_height"), height TSRMLS_CC); //更新类成员变量_height的值
RETURN_TRUE;
}
PHP_METHOD(Rectangle, getWidth)
{
zval *zWidth;
long width;
zWidth = zend_read_property(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("_width"), 0 TSRMLS_CC); //获取类成员变量_width的值
width = Z_LVAL_P(zWidth);
RETURN_LONG(width);
}
PHP_METHOD(Rectangle, getHeight)
{
zval *zHeight;
long height;
zHeight = zend_read_property(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("_height"), 0 TSRMLS_CC);
height = Z_LVAL_P(zHeight);
RETURN_LONG(height);
}
PHP_METHOD(Rectangle, getArea)
{
zval *zWidth,*zHeight;
long width,height,area;
zWidth = zend_read_property(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("_width"), 0 TSRMLS_CC);
zHeight = zend_read_property(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("_height"), 0 TSRMLS_CC);
width = Z_LVAL_P(zWidth);
height = Z_LVAL_P(zHeight);
area = width * height;
RETURN_LONG(area);
}
PHP_METHOD(Rectangle, getCircle)
{
zval *zWidth,*zHeight;
long width,height,circle;
zWidth = zend_read_property(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("_width"), 0 TSRMLS_CC);
zHeight = zend_read_property(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("_height"), 0 TSRMLS_CC);
width = Z_LVAL_P(zWidth);
height = Z_LVAL_P(zHeight);
circle = (width + height) * 2;
RETURN_LONG(circle);
}4,编译代码
cd php-5.2.8/ext/class_ext /usr/local/php/bin/phpize ./configure --with-php-config=/usr/local/php/bin/php-config make make install
/usr/local/php/lib/php/extensions/no-debug-non-zts-20060613/class_ext.so
修改php.ini 添加扩展extension_dir = "/usr/local/php/lib/php/extensions/no-debug-non-zts-20060613/"
[class_ext]
extension = class_ext.so
5,测试代码
$width = -10; $height = 12; $rectangle = new Rectangle($width, $height); $area = $rectangle->getArea(); var_dump($area); $circle = $rectangle->getCircle(); var_dump($circle); $clone = $rectangle->clone(); $_area = $clone->getArea(); var_dump($_area); $clone->setWidth(100); $clone->setHeight(200); $_area = $clone->getArea(); var_dump($_area); $width = $clone->getWidth(); var_dump($width); $height = $clone->getHeight(); var_dump($height);
int(12) int(26) int(12) int(20000) int(100) int(200)
PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号