首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 5 物件模型詳解:zend_object_value、PHP_METHOD、可見性與介面實作

     編輯:PHP 綜合知識

PHP 5 (Zend Engine 2) 重寫物件模型,引入 zend_object_value handle 機制、可見性控制、介面、靜態成員、魔術方法等現代 OOP 特性。本文以 sample3 擴展實作示範核心 API 與結構。

PHP 5 物件核心結構

  • zend_object_value:{ long handle; zend_object_handlers *handlers; }
    handle 為實例在 EG(objects_store) 中的索引,handlers 指向方法表/屬性存取器。
  • 實例儲存於 EG(objects_store),zval 僅持有 handle (IS_OBJECT 型別)。
  • 傳參為 handle 複製** (參考語意),非整個物件複製。

重建 sample3 擴展骨架

php-src/ext/sample3/
├── config.m4
├── php_sample3.h
└── sample3.c

類別定義與方法實作

#include "php_sample3.h"

zend_class_entry *php_sample3_sc_entry;

#define PHP_SAMPLE3_SC_NAME "Sample3_SecondClass"

// 方法實作:使用 PHP_METHOD 宏 (封裝 PHP_FUNCTION + 類別名)
PHP_METHOD(Sample3_SecondClass, helloWorld) {
    php_printf("Hello World\n");
}

// 靜態方法範例
PHP_METHOD(Sample3_SecondClass, staticGreet) {
    php_printf("Static Greeting\n");
}

// 方法表定義
static function_entry php_sample3_sc_functions[] = {
    PHP_ME(Sample3_SecondClass, helloWorld, NULL, ZEND_ACC_PUBLIC)
    PHP_ME(Sample3_SecondClass, staticGreet, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
    PHP_MALIAS(Sample3_SecondClass, sayHi, helloWorld, NULL, ZEND_ACC_PUBLIC)
    PHP_ME_MAPPING(hello, sample_hello_world, NULL)  // 映射程序式函式
    {NULL, NULL, NULL}
};

PHP_MINIT_FUNCTION(sample3) {
    zend_class_entry ce;
    INIT_CLASS_ENTRY(ce, PHP_SAMPLE3_SC_NAME, php_sample3_sc_functions);
    
    // 註冊內部類別
    php_sample3_sc_entry = zend_register_internal_class(&ce TSRMLS_CC);
    
    // 宣告屬性 (可見性控制)
    zend_declare_property_long(php_sample3_sc_entry, "publicProp", strlen("publicProp"), 0, ZEND_ACC_PUBLIC TSRMLS_CC);
    zend_declare_property_long(php_sample3_sc_entry, "protectedProp", strlen("protectedProp"), 0, ZEND_ACC_PROTECTED TSRMLS_CC);
    zend_declare_property_long(php_sample3_sc_entry, "privateProp", strlen("privateProp"), 0, ZEND_ACC_PRIVATE TSRMLS_CC);
    zend_declare_property_long(php_sample3_sc_entry, "staticProp", strlen("staticProp"), 0, ZEND_ACC_STATIC | ZEND_ACC_PUBLIC TSRMLS_CC);
    
    // 宣告類別常數
    zend_declare_class_constant_long(php_sample3_sc_entry, "VERSION", strlen("VERSION"), 1 TSRMLS_CC);
    
    return SUCCESS;
}

方法定義宏家族詳細解析

宏參數用途
PHP_METHOD(class, method)類別名、方法名定義實作函式,自動組合 zim_class_method 符號
PHP_ME(class, method, arg_info, flags)類別、方法、arg_info、旗標方法表註冊,支援可見性/靜態/抽象/最終
PHP_MALIAS(class, alias, orig, arg_info, flags)類別、別名、原方法、arg_info、旗標為同一實作建立別名 (如 sayHi → helloWorld)
PHP_ABSTRACT_ME(class, method, arg_info)類別、方法、arg_info宣告抽象方法 (無實作,供子類別實作/介面用)
PHP_ME_MAPPING(method, func, arg_info)方法名、程序式函式名、arg_info將程序式函式映射為類別方法 (如 mysqli 雙介面)

可見性與修飾旗標 (ZEND_ACC_*)

組合方式:位元或運算 ZEND_ACC_PUBLIC | ZEND_ACC_STATIC。

介面定義範例

zend_class_entry *php_sample3_iface_entry;

static function_entry php_sample3_iface_functions[] = {
    PHP_ABSTRACT_ME(Sample3_Interface, doSomething, NULL)
    PHP_ABSTRACT_ME(Sample3_Interface, getValue, NULL)
    {NULL, NULL, NULL}
};

PHP_MINIT_FUNCTION(sample3) {
    // ... 前面類別註冊 ...
    
    zend_class_entry ice;
    INIT_CLASS_ENTRY(ice, "Sample3_Interface", php_sample3_iface_functions);
    ice.ce_flags |= ZEND_ACC_INTERFACE; // 標記為介面
    php_sample3_iface_entry = zend_register_internal_interface(&ice TSRMLS_CC);
    
    // 類別實作介面
    zend_class_implements(php_sample3_sc_entry TSRMLS_CC, 1, php_sample3_iface_entry);
    
    return SUCCESS;
}

物件建立與屬性存取 (內部 API)

// 建立物件實例
zval *obj;
MAKE_STD_ZVAL(obj);
object_init_ex(obj, php_sample3_sc_entry);

// 寫入屬性
zend_update_property_long(php_sample3_sc_entry, obj, "publicProp", strlen("publicProp"), 42 TSRMLS_CC);

// 讀取屬性
zval **prop = zend_read_property(php_sample3_sc_entry, obj, "publicProp", strlen("publicProp"), 1 TSRMLS_CC);
long val = Z_LVAL_PP(prop);

// 靜態屬性存取
zval *static_prop = zend_read_static_property(php_sample3_sc_entry, "staticProp", strlen("staticProp"), 1 TSRMLS_CC);
Z_LVAL_P(static_prop) = 100;

特殊方法 (魔術方法) 支援

PHP 5 支援 __construct、__destruct、__call、__get、__set、__isset、__unset、__sleep、__wakeup、__toString、__invoke、__clone 等,內部以 ZEND_ACC_PUBLIC 註冊,引擎自動於對應時機呼叫。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
旗標含義
ZEND_ACC_PUBLIC公開 (預設)
ZEND_ACC_PROTECTED受保護 (繼承類可存取)
ZEND_ACC_PRIVATE私有 (僅本類別)
ZEND_ACC_STATIC靜態成員 (屬於類別,非實例)
ZEND_ACC_ABSTRACT抽象類別/方法
ZEND_ACC_FINAL最終類別/方法 (不可繼承/覆寫)
ZEND_ACC_INTERFACE介面類別
ZEND_ACC_IMPLICIT_ABSTRACT_CLASS隱式抽象類別 (含抽象方法)