The previous section briefly describes how to implement PHP extension using C language. For details, refer to the steps for developing PHP extension using C. That is to extend a function. Here we will explain how to use C extension class.
The classes to be implemented are as follows:
[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;
}
}
The steps to implement class extension are as follows: (first download the PHP source code, here the php-5.2.8 is used)
1. Create an extension skeleton
[Php]
Cd php-5.2.8/ext
./Ext_skel -- extname = class_ext
2. Modify compilation Parameters
[Php]
Cd php-5.2.8/ext/class_ext
Vi config. m4
Remove PHP_ARG_ENABLE (class_ext, whether to enable class_ext support, and
[-- Enable-class_ext Enable class_ext support]) The dnl before the two rows, modified:
[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. Write C code
[Php]
Cd php-5.2.8/ext/class_ext
Vi php_class_ext.h
# Add the declarative function to 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
# Declare the parameters of the method and register them in the function table.
[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 indicates the constructor, and ZEND_ACC_PUBLIC indicates that the access permission is PUBLIC.
[Php]
# Next, register and initialize the class in the module initialization Function
[Php]
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, and the third parameter is the class function list.
Rectangle_ce = zend_register_internal_class_ex (& Rectangle, NULL, NULL TSRMLS_CC); // registration class
Zend_declare_property_null (Rectangle_ce, ZEND_STRL ("_ width"), ZEND_ACC_PRIVATE TSRMLS_CC); // initialize the class attribute _ width
Zend_declare_property_null (Rectangle_ce, ZEND_STRL ("_ height"), ZEND_ACC_PRIVATE TSRMLS_CC); // initialize the attribute _ height of the class.
Return SUCCESS;
}
[Php]
# Add the implementation code of class member functions at the end of the file
[Php]
PHP_METHOD (Rectangle, _ construct)
{
Long width, height;
If (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC, "ll", & width, & height) = FAILURE) {// obtain the parameters _ width and _ height of the constructor.
WRONG_PARAM_COUNT;
}
If (width <= 0 ){
Width = 1; // If _ width is 0, the default value is 1.
}
If (height <= 0 ){
Height = 1; // If _ height is 0, the default value is 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); // initialize the object. The class of the object is Rectangle_ce.
Width = zend_read_property (Z_OBJCE_P (getThis (), getThis (), ZEND_STRL ("_ width"), 0 TSRMLS_CC); // obtain the value of the class member Variable _ width.
Height = zend_read_property (Z_OBJCE_P (getThis (), getThis (), ZEND_STRL ("_ height"), 0 TSRMLS_CC); // obtain 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 Rectangle_ce Class Object clone_obj attribute value _ width
Zend_update_property_long (Z_OBJCE_P (getThis (), getThis (), ZEND_STRL ("_ height"), height TSRMLS_CC); // update the Rectangle_ce Class Object clone_obj attribute value height _
RETURN_ZVAL (clone_obj, 1, 0); // return this 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); // obtain 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. Compile the code
[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
At this time, a so file will be generated in the php installation path, such
/Usr/local/php/lib/php/extensions/no-debug-non-zts-20060613/class_ext.so
Modify php. ini to add extended extension_dir = "/usr/local/php/lib/php/extensions/no-debug-non-zts-20060613 /"
[Class_ext]
Extension = class_ext.so
5. Test code
[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 );
Result output:
[Php]
Int (12)
Int (26)
Int (12)
Int (20000)
Int (100)
Int (200)