php扩展类开发实例
1 class Vector2D 2 { 3 private $_x; 4 private $_y; 5 6 /** 7 * Constructor. 8 */ 9 public function __construct($x = 0, $y = 0) 10 { 11 $this->_x = $x; 12 $this->_y = $y; 13 } 14 15 /** 16 * Generates a copy of $this vector. 17 * @return Vector2D A copy of $this vector. 18 */ 19 public function mycopy() 20 { 21 return new Vector2D($this->_x, $this->;_y); 22 } 23 24 /** 25 * Sets $this vector\'s x and y values, and thus length, to zero. 26 * @return Vector2D A reference to $this vector. 27 */ 28 public function zero() 29 { 30 $this->_x = 0; 31 $this->_y = 0; 32 return $this; 33 } 34 35 /** 36 * Whether or not $this vector is equal to zero, i.e. its x, y, and length are zero. 37 * @return Boolean True if vector is zero, otherwise false. 38 */ 39 public function isZero() 40 { 41 return $this->_x == 0 && $this->_y == 0; 42 } 43 public function getX() 44 { 45 return $this->_x; 46 } 47 public function getY() 48 { 49 return $this->_y; 50 } 51 }
第一步:建立扩展骨架
1 cd php-5.2.14/ext./ext_skel 2 3 --extname=vector
第二步:修改编译参数
1 cd php-5.2.14/ext/vector 2 vi config.m4
去掉
1 PHP_ARG_ENABLE(vector, whether to enable vector support, 2 [ --enable-vector Enable vector support])
两行前面的dnl
修改后为:
1 dnl Otherwise use enable: 2 3 PHP_ARG_ENABLE(vector, whether to enable vector support, 4 5 dnl Make sure that the comment is aligned: 6 7 [ --enable-vector Enable vector support])
第三步:编写代码
vim php_vector.h
在
PHP_FUNCTION(confirm_vector_compiled); /* For testing, remove later. */
后面增加声明函数
1 PHP_METHOD(Vector2D, __construct); 2 PHP_METHOD(Vector2D, mycopy); 3 PHP_METHOD(Vector2D, zero); 4 PHP_METHOD(Vector2D, isZero); 5 PHP_METHOD(Vector2D, getX); 6 PHP_METHOD(Vector2D, getY);
vim vector.c
声明方法的参数,注册到函数表中
1 ZEND_BEGIN_ARG_INFO(arg_construct, 2) //声明arg_construct为含有x,y的2个参数 2 ZEND_ARG_INFO(0, x) 3 ZEND_ARG_INFO(0, y) 4 ZEND_END_ARG_INFO() 5 6 zend_function_entry vector_functions[] = { 7 PHP_FE(confirm_vector_compiled, NULL) /* For testing, remove later. */ 8 PHP_ME(Vector2D, __construct, arg_construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)// 9 PHP_ME(Vector2D, mycopy, NULL, ZEND_ACC_PUBLIC) 10 PHP_ME(Vector2D, zero, NULL, ZEND_ACC_PUBLIC) 11 PHP_ME(Vector2D, isZero, NULL, ZEND_ACC_PUBLIC) 12 PHP_ME(Vector2D, getX, NULL, ZEND_ACC_PUBLIC) 13 PHP_ME(Vector2D, getY, NULL, ZEND_ACC_PUBLIC) 14 {NULL, NULL, NULL} /* Must be the last line in vector_functions[] */ 15 };
ZEND_ACC_CTOR表示为构造函数
ZEND_ACC_PUBLIC为访问权限标记,表示public访问权限
在模块初始化函数中注册并初始化类
1 zend_class_entry *Vector2D_ce; //类结构变量 2 PHP_MINIT_FUNCTION(vector) 3 { 4 /* If you have INI entries, uncomment these lines 5 REGISTER_INI_ENTRIES(); 6 */ 7 zend_class_entry Vector2D; 8 9 INIT_CLASS_ENTRY(Vector2D, "Vector2D", vector_functions);//第二个参数为类名,第三个参数为函数表 10 Vector2D_ce = zend_register_internal_class_ex(&Vector2D, NULL, NULL TSRMLS_CC);//注册类 11 12 zend_declare_property_null(Vector2D_ce, ZEND_STRL("_x"), ZEND_ACC_PRIVATE TSRMLS_CC);//初始化_x属性 13 zend_declare_property_null(Vector2D_ce, ZEND_STRL("_y"), ZEND_ACC_PRIVATE TSRMLS_CC);//初始化_y属性 14 15 return SUCCESS; 16 }
在文件最后面增加具体类方法的实现代码:
1 PHP_METHOD(Vector2D, __construct) { 2 long int x,y; 3 //获取x,y参数 4 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &x, &y) == FAILURE) { 5 WRONG_PARAM_COUNT; 6 } 7 8 //更改_x,_y属性值 9 zend_update_property_long(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("_x"), x TSRMLS_CC); 10 zend_update_property_long(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("_y"), y TSRMLS_CC); 11 12 RETURN_TRUE; 13 } 14 15 PHP_METHOD(Vector2D, mycopy) { 16 zval *copy_obj; 17 zval *x_value,*y_value; 18 19 MAKE_STD_ZVAL(copy_obj); 20 //初始化对象,对象所属的类为Vector2D_ce 21 object_init_ex(copy_obj, Vector2D_ce); 22 23 //获得_x,_y的属性值 24 x_value = zend_read_property(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("_x"), 0 TSRMLS_CC); 25 y_value = zend_read_property(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("_y"), 0 TSRMLS_CC); 26 27 //更新Vector2D_ce类对象copy_obj的属性值_x,_y 28 zend_update_property(Z_OBJCE_P(getThis()), copy_obj, ZEND_STRL("_x"), x_value TSRMLS_CC); 29 zend_update_property(Z_OBJCE_P(getThis()), copy_obj, ZEND_STRL("_y"), y_value TSRMLS_CC); 30 //返回该对象 31 RETURN_ZVAL(copy_obj, 1, 0); 32 } 33 34 PHP_METHOD(Vector2D, zero) { 35 //更改_x,_y的属性值为0 36 zend_update_property_long(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("_x"), 0 TSRMLS_CC); 37 zend_update_property_long(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("_y"), 0 TSRMLS_CC); 38 //返回当前类实例 39 RETURN_ZVAL(getThis(), 1, 0);; 40 } 41 42 PHP_METHOD(Vector2D, isZero) { 43 44 zval *zx, *zy; 45 long x,y; 46 // 获得_x,_y的属性值 47 zx = zend_read_property(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("_x"), 0 TSRMLS_CC); 48 zy = zend_read_property(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("_y"), 0 TSRMLS_CC); 49 50 x = Z_LVAL_P(zx); 51 y = Z_LVAL_P(zy); 52 53 if(x==0 && y==0){ 54 RETURN_BOOL(1); 55 }else{ 56 RETURN_BOOL(0); 57 } 58 59 } 60 61 PHP_METHOD(Vector2D, getX) { 62 63 zval *zx; 64 long x; 65 66 zx = zend_read_property(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("_x"), 0 TSRMLS_CC); 67 x = Z_LVAL_P(zx); 68 69 RETURN_LONG(x); 70 } 71 72 PHP_METHOD(Vector2D, getY) { 73 74 zval *zy; 75 long y; 76 77 zy = zend_read_property(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("_y"), 0 TSRMLS_CC); 78 y = Z_LVAL_P(zy); 79 80 RETURN_LONG(y); 81 }
第四步:编译代码
1 cd php-5.2.6/ext/vector 2 /opt/module/php/bin/phpize 3 ./configure --with-php-config=/opt/module/php/bin/php-config 4 make 5 make install
第五步:配置扩展
在[PHP]模块下增加:
1 extension = vector.so 2 service httpd restart