首頁 後端開發 php教程 深入了解php自訂函數的參數傳遞

深入了解php自訂函數的參數傳遞

Jun 26, 2017 pm 01:29 PM
php 了解 函數 參數 深入 自訂

函數的參數

函數的定義只是將函數名稱註冊到函數清單的過程。

1、使用者自訂函數的參數

我們知道對於函數的參數檢查是透過zend_do_receive_arg函數來實現的,在此函數中對於參數的關鍵程式碼如下:

CG(active_op_array)->arg_info = erealloc(CG(active_op_array)->arg_info,
        sizeof(zend_arg_info)*(CG(active_op_array)->num_args));
cur_arg_info = &CG(active_op_array)->arg_info[CG(active_op_array)->num_args-1];
cur_arg_info->name = estrndup(varname->u.constant.value.str.val,
        varname->u.constant.value.str.len);
cur_arg_info->name_len = varname->u.constant.value.str.len;
cur_arg_info->array_type_hint = 0;
cur_arg_info->allow_null = 1;
cur_arg_info->pass_by_reference = pass_by_reference;
cur_arg_info->class_name = NULL;
cur_arg_info->class_name_len = 0;
登入後複製

 整個參數的傳遞是透過給中間程式碼的arg_info欄位執行賦值操作完成。關鍵點是在arg_info字段,arg_info字段的結構如下:

typedef struct _zend_arg_info {
    const char *name;   /*参数的名称*/
    zend_uint name_len;     /*参数名称的长度*/
    const char *class_name; /* 类名*/
     zend_uint class_name_len;   /*类名长度*/
    zend_bool array_type_hint;  /*数组类型提示*/
    zend_bool allow_null;   /*是否允许为NULLͺ*/
    zend_bool pass_by_reference;    /*是否引用传递*/
    zend_bool return_reference; 
    int required_num_args;  
} zend_arg_info;
登入後複製

參數的值傳遞和參數傳遞的區別是透過pass_by_reference參數在產生中間程式碼時實現的。

  對於參數的個數,中間程式碼中包含的arg_nums欄位在每次執行**zend_do_receive_argxx時都會加1.如下程式碼:

CG(active_op_array)->num_args++;
登入後複製

  且目前參數的索引為CG( active_op_array)->num_args-1.如下程式碼:

cur_arg_info = &CG(active_op_array)->arg_info[CG(active_op_array)->num_args-1];
登入後複製

  以上的分析是針對函數定義時的參數設置,這些參數是固定的。而在實際寫程式時可能我們會用到可變參數。此時我們會用到函式func_num_args和func_get_args。它們以內部函數存在。於是在Zend\zend_builtin_functions.c檔中找到這兩個函數的實作。我們先來看func_num_args函數的實現,其程式碼如下:

/* {{{ proto int func_num_args(void)
   Get the number of arguments that were passed to the function */
ZEND_FUNCTION(func_num_args)
{
    zend_execute_data *ex = EG(current_execute_data)->prev_execute_data;
 
    if (ex && ex->function_state.arguments) {
        RETURN_LONG((long)(zend_uintptr_t)*(ex->function_state.arguments));
    } else {
        zend_error(E_WARNING,
"func_num_args():  Called from the global scope - no function context");
        RETURN_LONG(-1);
    }
}
/* }}} */
登入後複製

 在存在ex->function_state.arguments的情況下,及函數呼叫時,傳回ex->function_state.arguments轉換後的值,否則顯示錯誤並返回-1。這裡最關鍵的一點是EG(current_execute_data)。這個變數存放的是當前執行程序或函數的數據,此時我們需要取前一個執行程序的數據,為什麼呢?因為這個函數的呼叫是在進入函數後執行的。函數的相關資料等都在先前執行過程中,於是呼叫的是:

zend_execute_data *ex = EG(current_execute_data)->prev_execute_data;
登入後複製

2、內部函數的參數

以常見的count函數為例,其參數處理部分的程式碼如下:

/* {{{ proto int count(mixed var [, int mode])
   Count the number of elements in a variable (usually an array) */
PHP_FUNCTION(count)
{
    zval *array;
    long mode = COUNT_NORMAL;
 
    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|l",
         &array, &mode) == FAILURE) {
        return;
    }
    ... //省略
}
登入後複製

 這裡包含了兩個運算:一個是取參數的個數,一個是解析參數清單。

(1)取參數的個數

取參數的個數是透過ZEND_NUM_ARGS()巨集來實現的,定義如下:

#define ZEND_NUM_ARGS()     (ht)
登入後複製

ht是在Zend /zend.h檔案中定義的巨集INTERNAL_FUNCTION_PARAMETERS中的ht,如下

#define INTERNAL_FUNCTION_PARAMETERS int ht, zval *return_value,
zval **return_value_ptr, zval *this_ptr, int return_value_used TSRMLS_DC
登入後複製

(2)解析參數清單

PHP內部函數在解析參數時使用的是zend_parse_parameters。它可以大大簡化參數的接收處理工作,雖然它在處理可變參數時還有點弱。

其宣告如下:

ZEND_API int zend_parse_parameters(int num_args TSRMLS_DC, char *type_spec, 
...)
登入後複製

第一個參數num_args表示表示想要接收的參數個數,我們經常使用ZEND_NUM_ARGS()來表示對傳入的參數「有多少要多少”

第二個參數應該是巨集TSRMLS_CC。

第三個參數type_spec是一個字串,用來指定我們所期待接收的各個參數的類型,有點類似於printf中指定輸出格式的那個格式化字串

剩下的參數就是我們用來接收PHP參數值的變數的指標。

zend_parse_parameters()在解析參數的同時戶盡可能的轉換參數類型,這樣就可以確保我們總是能得到所期望的類型的變數

以上是深入了解php自訂函數的參數傳遞的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡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脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
4 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

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

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

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

適用於 Ubuntu 和 Debian 的 PHP 8.4 安裝和升級指南 適用於 Ubuntu 和 Debian 的 PHP 8.4 安裝和升級指南 Dec 24, 2024 pm 04:42 PM

PHP 8.4 帶來了多項新功能、安全性改進和效能改進,同時棄用和刪除了大量功能。 本指南介紹如何在 Ubuntu、Debian 或其衍生版本上安裝 PHP 8.4 或升級到 PHP 8.4

討論 CakePHP 討論 CakePHP Sep 10, 2024 pm 05:28 PM

CakePHP 是 PHP 的開源框架。它旨在使應用程式的開發、部署和維護變得更加容易。 CakePHP 基於類似 MVC 的架構,功能強大且易於掌握。模型、視圖和控制器 gu

CakePHP 檔案上傳 CakePHP 檔案上傳 Sep 10, 2024 pm 05:27 PM

為了進行文件上傳,我們將使用表單助理。這是文件上傳的範例。

如何設定 Visual Studio Code (VS Code) 進行 PHP 開發 如何設定 Visual Studio Code (VS Code) 進行 PHP 開發 Dec 20, 2024 am 11:31 AM

Visual Studio Code,也稱為 VS Code,是一個免費的原始碼編輯器 - 或整合開發環境 (IDE) - 可用於所有主要作業系統。 VS Code 擁有大量針對多種程式語言的擴展,可以輕鬆編寫

CakePHP 快速指南 CakePHP 快速指南 Sep 10, 2024 pm 05:27 PM

CakePHP 是一個開源MVC 框架。它使應用程式的開發、部署和維護變得更加容易。 CakePHP 有許多函式庫可以減少大多數常見任務的過載。

您如何在PHP中解析和處理HTML/XML? 您如何在PHP中解析和處理HTML/XML? Feb 07, 2025 am 11:57 AM

本教程演示瞭如何使用PHP有效地處理XML文檔。 XML(可擴展的標記語言)是一種用於人類可讀性和機器解析的多功能文本標記語言。它通常用於數據存儲

在PHP API中說明JSON Web令牌(JWT)及其用例。 在PHP API中說明JSON Web令牌(JWT)及其用例。 Apr 05, 2025 am 12:04 AM

JWT是一種基於JSON的開放標準,用於在各方之間安全地傳輸信息,主要用於身份驗證和信息交換。 1.JWT由Header、Payload和Signature三部分組成。 2.JWT的工作原理包括生成JWT、驗證JWT和解析Payload三個步驟。 3.在PHP中使用JWT進行身份驗證時,可以生成和驗證JWT,並在高級用法中包含用戶角色和權限信息。 4.常見錯誤包括簽名驗證失敗、令牌過期和Payload過大,調試技巧包括使用調試工具和日誌記錄。 5.性能優化和最佳實踐包括使用合適的簽名算法、合理設置有效期、

php程序在字符串中計數元音 php程序在字符串中計數元音 Feb 07, 2025 pm 12:12 PM

字符串是由字符組成的序列,包括字母、數字和符號。本教程將學習如何使用不同的方法在PHP中計算給定字符串中元音的數量。英語中的元音是a、e、i、o、u,它們可以是大寫或小寫。 什麼是元音? 元音是代表特定語音的字母字符。英語中共有五個元音,包括大寫和小寫: a, e, i, o, u 示例 1 輸入:字符串 = "Tutorialspoint" 輸出:6 解釋 字符串 "Tutorialspoint" 中的元音是 u、o、i、a、o、i。總共有 6 個元

See all articles