首頁 後端開發 php教程 用C实现PHP扩展类的步骤_PHP教程

用C实现PHP扩展类的步骤_PHP教程

Jul 14, 2016 am 10:06 AM
php 實現 開發 擴充 步驟 簡單 類別 語言

   前面简单介绍了用C语言实现PHP扩展的步骤,见用C开发PHP扩展的步骤,那个是扩展一个函数,这里讲述一下如何用C扩展类。

    准备实现的类如下:

   

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

实现类扩展的步骤如下:(首先下载PHP源码,这里使用的是php-5.2.8)

1,建立扩展骨架

[php] 
cd php-5.2.8/ext 
./ext_skel --extname=class_ext 

2,修改编译参数
[php] 
cd php-5.2.8/ext/class_ext 
vi config.m4 
去掉PHP_ARG_ENABLE(class_ext, whether to enable class_ext support,和
[   --enable-class_ext       Enable class_ext support])两行前面的dnl,修改后为:


[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,编写C代码

[php] 
cd php-5.2.8/ext/class_ext 
vi php_class_ext.h 
#在 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 
#申明方法的参数,注册到函数表中 

[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内部类结构变量 
PHP_MINIT_FUNCTION(class_ext) 

    zend_class_entry Rectangle; 
    INIT_CLASS_ENTRY(Rectanble, "Rectangle", class_ext_functions); //第二个参数为类名,第三个参数为类的函数列表 
    Rectangle_ce = zend_register_internal_class_ex(&Rectangle, NULL, NULL TSRMLS_CC); //注册类 
    zend_declare_property_null(Rectangle_ce, ZEND_STRL("_width"), ZEND_ACC_PRIVATE TSRMLS_CC); //初始化类的属性_width 
    zend_declare_property_null(Rectangle_ce, ZEND_STRL("_height"), ZEND_ACC_PRIVATE TSRMLS_CC);  //初始化类的属性_height 
    return SUCCESS; 

[php] 
#在文件最后增加类的成员函数的具体实现代码 
[php] 
PHP_METHOD(Rectangle, __construct) 

    long width,height; 
    if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &width, &height) == FAILURE){ //获取构造函数的两个函数参数_width和_height 
        WRONG_PARAM_COUNT; 
    } 
    if( width         width = 1; //如果_width为0,则赋默认值1 
    } 
    if( height         height = 1; //如果_height为0,则赋默认值1 
    } 
    zend_update_property_long(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("_width"), width TSRMLS_CC); //更新类成员变量_width的值 
    zend_update_property_long(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("_height"), height TSRMLS_CC);  //更新类成员变量_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); //初始化对象,对象所属的类为Rectangle_ce 
    width = zend_read_property(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("_width"), 0 TSRMLS_CC); //获取类成员变量_width的值 
    height = zend_read_property(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("_height"), 0 TSRMLS_CC); //获取类成员变量_height的值 
    zend_update_property_long(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("_width"), width TSRMLS_CC); //更新Rectangle_ce类对象clone_obj的属性值_width 
    zend_update_property_long(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("_height"), height TSRMLS_CC); //更新Rectangle_ce类对象clone_obj的属性值_height 
    RETURN_ZVAL(clone_obj, 1, 0);  //返回该对象 

 
PHP_METHOD(Rectangle, setWidth() 

    long width; 
    if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &width) == FAILURE){ 
        WRONG_PARAM_COUNT; 
    } 
    if( width         width = 1; 
    } 
    zend_update_property_long(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("_width"), width TSRMLS_CC); //更新类成员变量_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         height = 1; 
    } 
    zend_update_property_long(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("_height"), height TSRMLS_CC); //更新类成员变量_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扩展类。 准备实现的类如...
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1677
14
CakePHP 教程
1431
52
Laravel 教程
1334
25
PHP教程
1280
29
C# 教程
1257
24
如果session_start()被多次調用會發生什麼? 如果session_start()被多次調用會發生什麼? Apr 25, 2025 am 12:06 AM

多次調用session_start()會導致警告信息和可能的數據覆蓋。 1)PHP會發出警告,提示session已啟動。 2)可能導致session數據意外覆蓋。 3)使用session_status()檢查session狀態,避免重複調用。

作曲家:通過AI的幫助開發PHP 作曲家:通過AI的幫助開發PHP Apr 29, 2025 am 12:27 AM

AI可以幫助優化Composer的使用,具體方法包括:1.依賴管理優化:AI分析依賴關係,建議最佳版本組合,減少衝突。 2.自動化代碼生成:AI生成符合最佳實踐的composer.json文件。 3.代碼質量提升:AI檢測潛在問題,提供優化建議,提高代碼質量。這些方法通過機器學習和自然語言處理技術實現,幫助開發者提高效率和代碼質量。

session_start()函數的意義是什麼? session_start()函數的意義是什麼? May 03, 2025 am 12:18 AM

session_start()iscucialinphpformanagingusersessions.1)ItInitiateSanewsessionifnoneexists,2)resumesanexistingsessions,and3)setsasesessionCookieforContinuityActinuityAccontinuityAcconActInityAcconActInityAcconAccRequests,EnablingApplicationsApplicationsLikeUseAppericationLikeUseAthenticationalticationaltication and PersersonalizedContentent。

如何使用MySQL的函數進行數據處理和計算 如何使用MySQL的函數進行數據處理和計算 Apr 29, 2025 pm 04:21 PM

MySQL函數可用於數據處理和計算。 1.基本用法包括字符串處理、日期計算和數學運算。 2.高級用法涉及結合多個函數實現複雜操作。 3.性能優化需避免在WHERE子句中使用函數,並使用GROUPBY和臨時表。

H5:HTML5的關鍵改進 H5:HTML5的關鍵改進 Apr 28, 2025 am 12:26 AM

HTML5帶來了五個關鍵改進:1.語義化標籤提升了代碼清晰度和SEO效果;2.多媒體支持簡化了視頻和音頻嵌入;3.表單增強簡化了驗證;4.離線與本地存儲提高了用戶體驗;5.畫布與圖形功能增強了網頁的可視化效果。

作曲家:PHP開發人員的軟件包經理 作曲家:PHP開發人員的軟件包經理 May 02, 2025 am 12:23 AM

Composer是PHP的依賴管理工具,通過composer.json文件管理項目依賴。 1)解析composer.json獲取依賴信息;2)解析依賴關係形成依賴樹;3)從Packagist下載並安裝依賴到vendor目錄;4)生成composer.lock文件鎖定依賴版本,確保團隊一致性和項目可維護性。

MySQL的字符集和排序規則如何配置 MySQL的字符集和排序規則如何配置 Apr 29, 2025 pm 04:06 PM

在MySQL中配置字符集和排序規則的方法包括:1.設置服務器級別的字符集和排序規則:SETNAMES'utf8';SETCHARACTERSETutf8;SETCOLLATION_CONNECTION='utf8_general_ci';2.創建使用特定字符集和排序規則的數據庫:CREATEDATABASEexample_dbCHARACTERSETutf8COLLATEutf8_general_ci;3.創建表時指定字符集和排序規則:CREATETABLEexample_table(idINT

怎樣在C  中使用type traits? 怎樣在C 中使用type traits? Apr 28, 2025 pm 08:18 PM

typetraits在C 中用於編譯時類型檢查和操作,提升代碼的靈活性和類型安全性。 1)通過std::is_integral和std::is_floating_point等進行類型判斷,實現高效的類型檢查和輸出。 2)使用std::is_trivially_copyable優化vector拷貝,根據類型選擇不同的拷貝策略。 3)注意編譯時決策、類型安全、性能優化和代碼複雜性,合理使用typetraits可以大大提升代碼質量。

See all articles