Heim  >  Artikel  >  Backend-Entwicklung  >  用C实现PHP扩展类的步骤_PHP教程

用C实现PHP扩展类的步骤_PHP教程

WBOY
WBOYOriginal
2016-07-14 10:06:48799Durchsuche

   前面简单介绍了用C语言实现PHP扩展的步骤,见用C开发PHP扩展的步骤,那个是扩展一个函数,这里讲述一下如何用C扩展类。

    准备实现的类如下:

   

[php] 
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 

2,修改编译参数
[php] 
cd php-5.2.8/ext/class_ext 
vi config.m4 
去掉PHP_ARG_ENABLE(class_ext, whether to enable class_ext support,和
[   --enable-class_ext       Enable class_ext support])两行前面的dnl,修改后为:


[php]
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]) 

3,编写C代码

[php] 
cd php-5.2.8/ext/class_ext 
vi php_class_ext.h 
#在 PHP_FUNCTION(confirm_class_ext_compiled); 后面增加申明函数; 

[php] 
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); 

[php] 
vi class_ext.c 
#申明方法的参数,注册到函数表中 

[php] 
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[] */ 
}; 
[php] 
#其中ZEND_ACC_CTOR表示构造函数,ZEND_ACC_PUBLIC表示访问权限为PUBLIC。 
[php] 
#接下来,在模块初始化函数中注册并初始化类 

[php] 
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] 
#在文件最后增加类的成员函数的具体实现代码 
[php] 
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         width = 1; //如果_width为0,则赋默认值1 
    } 
    if( height         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         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         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,编译代码

[php] 
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 

此时会在php的安装路径下产生一个so文件,比如
/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,测试代码

[php] 
$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); 

结果输出:
[php] 
int(12) 
int(26) 
int(12) 
int(20000) 
int(100) 
int(200) 

 

 

 

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/477917.htmlTechArticle前面简单介绍了用C语言实现PHP扩展的步骤,见用C开发PHP扩展的步骤,那个是扩展一个函数,这里讲述一下如何用C扩展类。 准备实现的类如...
Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn