Home >Backend Development >PHP Tutorial > 用C兑现PHP扩展类

用C兑现PHP扩展类

WBOY
WBOYOriginal
2016-06-13 13:05:37808browse

用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,建立扩展骨架

cd php-5.2.8/ext
./ext_skel --extname=class_ext

2,修改编译参数

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,修改后为:

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代码

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 <br>
<p>4,编译代码</p>
<p></p>
<pre name="code" class="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,测试代码

$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)

6,Over!







Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn