Home  >  Article  >  Backend Development  >  Steps to implement PHP extension class in C_PHP tutorial

Steps to implement PHP extension class in C_PHP tutorial

WBOY
WBOYOriginal
2016-07-14 10:06:48838browse

Previously we briefly introduced the steps to implement PHP extension using C language. See the steps to develop PHP extension using C. That is to extend a function. Here we will explain how to use C to extend a 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 we use php-5.2.8)

1. Create an extended 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 in front of the two lines, modified to:


[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 declaration function after 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表示构造函数,ZEND_ACC_PUBLIC表示访问权限为PUBLIC。 
[php] 
#接下来,在模块初始化函数中注册并初始化类 

[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 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); //Initialize the properties of the class _height
Return SUCCESS;
}
[php]
#Add the specific implementation code of the class member function 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){ //Get the two function parameters _width and _height of the constructor
WRONG_PARAM_COUNT;
}  
If( width <= 0 ) {
           width = 1; //If _width is 0, assign the default value 1
}  
If( height <= 0 ) {
​​​​ height = 1; //If _height is 0, assign the default value 1
}  
zend_update_property_long(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("_width"), width TSRMLS_CC); //Update the value of class member variable _width
zend_update_property_long(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("_height"), height TSRMLS_CC); //Update the value of 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 to which the object belongs is Rectangle_ce
width = zend_read_property(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("_width"), 0 TSRMLS_CC); //Get the value of class member variable _width
height = zend_read_property(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("_height"), 0 TSRMLS_CC); //Get the value of class member variable _height
zend_update_property_long(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("_width"), width TSRMLS_CC); //Update the attribute value _width of the Rectangle_ce class object clone_obj
zend_update_property_long(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("_height"), height TSRMLS_CC); //Update the property value _height of the Rectangle_ce class object clone_obj
RETURN_ZVAL(clone_obj, 1, 0); //Return 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 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 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); //获取类成员变量_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,编译代码

[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,测试代码

[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); 

结果输出:
[php] 
int(12) 
int(26) 
int(12) 
int(20000) 
int(100) 
int(200) 

 

 

 

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/477917.htmlTechArticle前面简单介绍了用C语言实现PHP扩展的步骤,见用C开发PHP扩展的步骤,那个是扩展一个函数,这里讲述一下如何用C扩展类。 准备实现的类如...
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