Implementing PHP extension classes with C
The steps to implement PHP extensions in C are briefly described in the previous step, see the steps to develop PHP extensions in C, which is to extend a function, which describes how to use the C extension class.
The classes that are ready to be implemented are:
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;}}
The steps to implement the class extension are as follows: (First download PHP source code, here is the use of php-5.2.8)
1. Build an extended skeleton
CD Php-5.2.8/ext./ext_skel--extname=class_ext
2, modify the compilation parameters
CD PHP-5.2.8/EXT/CLASS_EXTVI CONFIG.M4
Remove Php_arg_enable (class_ext, whether to ENABLE Class_ext support, and
[--enable-class_ext enable class_ext support]) DNL in front of two lines, modified to:
DNL Otherwise Use enable: php_arg_enable (Class_ext, whether to enable Class_ext support, DNL Make sure that the CO Mment is aligned: [ --enable-class_ext enable class_ext support])
3, write C code
CD Php-5.2.8/ext/class_extvi php_class_ext.h# in Php_function (confirm_class_ext_compiled); Add the declaration function later;
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# Declare the parameters of the method, register it in the function table
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 (Rec Tangle, getheight, NULL, zend_acc_public) Php_me (Rectangle, Getarea, NULL, zend_acc_public) Php_me (Rectangle, Getcir CLE, NULL, zend_acc_public) {null, NULL, NULL}/* must is the last line in class_ext_functions[] */};
#其中ZEND_ACC_CTOR表示构造函数, zend_acc_public indicates that access rights are public.
#接下来, register and initialize the class in the module initialization function
Zend_class_entry *rectangle_ce; Zend internal class structure variable php_minit_function (class_ext) { zend_class_entry Rectangle; Init_class_entry (rectanble, "Rectangle", class_ext_functions); The second parameter is the class name, the third argument is the function list of the class rectangle_ce = ZEND_REGISTER_INTERNAL_CLASS_EX (&rectangle, NULL, null TSRMLS_CC); Register class Zend_declare_property_null (Rectangle_ce, Zend_strl ("_width"), zend_acc_private tsrmls_cc);//Initialize the properties of the class _width zend_declare_property_null (Rectangle_ce, Zend_strl ("_height"), Zend_acc_private tsrmls_cc); Initializes the properties of the class _height return SUCCESS;}
#在文件最后增加类的成员函数的具体实现代码
Php_method (Rectangle, __construct) {long width,height; if (Zend_parse_parameters (Zend_num_args () tsrmls_cc, "ll", &width, &height) = = FAILURE) {//Get constructor Two function arguments _ Width and _height wrong_param_count; if (width <= 0) {width = 1;//If _width is 0, assign the default value of 1} if (height <= 0) {height = 1;//If _he Ight is 0, assigns the default value of 1} zend_update_property_long (Z_objce_p (Getthis ()), Getthis (), Zend_strl ("_width"), width tsrmls_cc); Update the value of the class member variable _width zend_update_property_long (z_objce_p (Getthis ()), Getthis (), Zend_strl ("_height"), Height tsrmls_cc ); Update the value of the class member variable _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); Initializes the object, the class to which the object belongs is rectangle_ce width = zend_read_property (z_objce_p (Getthis ()), Getthis (), Zend_strl ("_width"), 0 tsrmls _CC); Gets the value of the class member variable _width height = zend_read_property (z_objce_p (Getthis ()), Getthis (), Zend_strl ("_height"), 0 tsrmls_CC); Gets the value of the class member variable _height zend_update_property_long (z_objce_p (Getthis ()), Getthis (), Zend_strl ("_width"), width tsrmls_cc) ; Update the property values of the Rectangle_ce class object Clone_obj _width Zend_update_property_long (z_objce_p (Getthis ()), Getthis (), ZEND_STRL ("_ Height "), height tsrmls_cc); Update the property values of the Rectangle_ce class object Clone_obj _height return_zval (clone_obj, 1, 0); Returns the object}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); Update the value of the class member variable _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); Update the value of the class member variable _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); Gets the value of the class member variable _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, compiling the code
CD Php-5.2.8/ext/class_ext/usr/local/php/bin/phpize./configure--with-php-config=/usr/local/php/bin/ Php-configmake make Install
A so file is generated under the installation path of PHP, such as
/usr/local/php/lib/php/extensions/no-debug-non-zts-20060613/class_ext.so
Modify php.ini Add extension Extension_dir = "/usr/local/php/lib/php/extensions/no-debug-non-zts-20060613/"
[Class_ext]
Extension = class_ext.so
5, test the code
$width = -10; $height = n; $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 (+), $clone->setheight (+), $_area = $clone->getarea (); Var_dump ($_ Area), $width = $clone->getwidth (), Var_dump ($width), $height = $clone->getheight (); Var_dump ($height);
Result output:
int (+) int (+) int (20000) int (+) int (200)
6,over!