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

PHP 擴展開發:函式回傳值機制與 RETURN_VALUE 宏詳解

     編輯:PHP 綜合知識

PHP 內部函式不直接 return zval*,而是由 Zend 引擎預先分配 return_value 參數,擴展僅需填充該 zval。本文解析回傳值機制、ZVAL_* 與 RETVAL_* 宏家族用法。

核心機制:return_value 參數

// 錯誤示範:手動分配 zval 並 return
PHP_FUNCTION(sample_wrong) {
    zval *retval;
    MAKE_STD_ZVAL(retval);
    ZVAL_LONG(retval, 42);
    return retval;  // 錯誤!引擎不接收回傳值
}

// 正確示範:填充預分配的 return_value
PHP_FUNCTION(sample_long) {
    ZVAL_LONG(return_value, 42);
    return;  // 無需回傳值
}

ZVAL_LONG 宏展開

// 等價於:
Z_TYPE_P(return_value) = IS_LONG;
Z_LVAL_P(return_value) = 42;

// 或直接存取:
return_value->type = IS_LONG;
return_value->value.lval = 42;

注意:return_value 的 refcount、is_ref 由引擎管理,**擴展不可直接修改**。

RETVAL_* 宏家族:省略 return_value 參數

實戰範例:整合到 sample 擴展

// sample.c 新增函式
PHP_FUNCTION(sample_long) {
    RETVAL_LONG(42);
    return;
}

PHP_FUNCTION(sample_hello_world) {
    RETVAL_STRING("Hello World!", 1);
    return;
}

// function_entry 陣列註冊
static function_entry php_sample_functions[] = {
    PHP_FE(sample_hello_world, NULL)
    PHP_FE(sample_long, NULL)
    {NULL, NULL, NULL}
};

重新編譯測試

make clean && make && make install
php -r 'var_dump(sample_long());'
// 輸出: int(42)

php -r 'var_dump(sample_hello_world());'
// 輸出: string(12) "Hello World!"

進階:回傳陣列與物件

PHP_FUNCTION(sample_array) {
    array_init(return_value);
    add_assoc_long(return_value, "id", 1);
    add_assoc_string(return_value, "name", "test", 1);
    add_next_index_long(return_value, 100);
    // 無需 return,return_value 已填充
}

關鍵 API:array_init()、add_assoc_*()、add_next_index_*()、add_index_*()。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
標準宏簡寫宏說明
ZVAL_LONG(zv, val)RETVAL_LONG(val)整數
ZVAL_DOUBLE(zv, val)RETVAL_DOUBLE(val)浮點數
ZVAL_STRING(zv, str, dup)RETVAL_STRING(str, dup)字串 (dup=1 複製)
ZVAL_STRINGL(zv, str, len, dup)RETVAL_STRINGL(str, len, dup)二進制字串
ZVAL_BOOL(zv, val)RETVAL_BOOL(val)布林
ZVAL_NULL(zv)RETVAL_NULL()NULL
ZVAL_RESOURCE(zv, id)RETVAL_RESOURCE(id)資源 ID
ZVAL_ZVAL(dst, src, copy, dtor)RETVAL_ZVAL(zv, copy, dtor)複製 zval