Steps to implement PHP extension class in C_PHP tutorial
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)

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

In this chapter, we will understand the Environment Variables, General Configuration, Database Configuration and Email Configuration in CakePHP.

PHP 8.4 brings several new features, security improvements, and performance improvements with healthy amounts of feature deprecations and removals. This guide explains how to install PHP 8.4 or upgrade to PHP 8.4 on Ubuntu, Debian, or their derivati

To work with date and time in cakephp4, we are going to make use of the available FrozenTime class.

To work on file upload we are going to use the form helper. Here, is an example for file upload.

In this chapter, we are going to learn the following topics related to routing ?

CakePHP is an open-source framework for PHP. It is intended to make developing, deploying and maintaining applications much easier. CakePHP is based on a MVC-like architecture that is both powerful and easy to grasp. Models, Views, and Controllers gu

Validator can be created by adding the following two lines in the controller.

Working with database in CakePHP is very easy. We will understand the CRUD (Create, Read, Update, Delete) operations in this chapter.
