首页 > 技术文章 > php扩展类开发实例

lsl8966 2013-11-26 18:05 原文

 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

 

推荐阅读