成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

php 內(nèi)核探秘之 PHP_FUNCTION 宏

Rindia / 2017人閱讀

摘要:語(yǔ)言中的宏,我認(rèn)為,可以理解為一種簡(jiǎn)單的封裝。通過宏定義,可以對(duì)開發(fā)者隱去一些細(xì)節(jié),讓開發(fā)者在使用簡(jiǎn)單的語(yǔ)法來完成重復(fù)的復(fù)雜的編碼。當(dāng)然,宏定義還有其它的用途,但是,我們?cè)谏婕暗降木褪沁@個(gè)作用。我們看到,在宏定義中,使用了另外的宏。

本人也只是個(gè)初入門的菜鳥,因?qū)夹g(shù)有著向往,故在“無趣”的工作之余,盡自己所能提升自己。由于我的 C 語(yǔ)言功底也有限,故本文的深度也有限,如有幸得大牛閱讀,還望指導(dǎo)一二,小弟感激不盡。

PHP 的函數(shù)

作為 PHPer,我們幾乎每天都在寫函數(shù),我們一定會(huì)好奇,那些 PHP 內(nèi)置的函數(shù),是長(zhǎng)什么樣子的。如果寫過 PHP 擴(kuò)展的話,一定知道這個(gè)宏:PHP_FUNCTION。在定義一個(gè)函數(shù)的時(shí)候,這樣來使用這個(gè)宏。例如 array_change_key_case,它的定義是這樣的:PHP_FUNCTION(array_change_key_case)。沒錯(cuò),就是這么簡(jiǎn)單。但是,在這個(gè)簡(jiǎn)單的背后,卻沒有這么簡(jiǎn)單。

PHP_FUNCTION 追根溯源

相信對(duì)這篇文章感興趣的同學(xué),一定多少對(duì) C 語(yǔ)言以及它的宏定義有一定的了解。如果沒有,也不要緊,我這里來簡(jiǎn)單解釋一下,什么是宏。

C 語(yǔ)言中的宏,我認(rèn)為,可以理解為一種簡(jiǎn)單的封裝。通過宏定義,可以對(duì)開發(fā)者隱去一些細(xì)節(jié),讓開發(fā)者在使用簡(jiǎn)單的語(yǔ)法來完成重復(fù)的復(fù)雜的編碼。當(dāng)然,宏定義還有其它的用途,但是,我們?cè)?PHP_FUNCTION 涉及到的就是這個(gè)作用。有下面的代碼。

#define TEST(test) void test(int a)

TEST(haha)

宏,就是完全的替換,即使用后面的語(yǔ)句替換前面的。那么對(duì)于下面的 TEST(haha) 就相當(dāng)于下面的樣子。

void haha(int a)
PHP_FUNCTION 的定義

首先,我們要定義函數(shù),這樣使用這個(gè)宏。

PHP_FUNCTION(array_change_key_case)
{
    // TODO
}

我們?cè)?php-src/main/php.h 中找到了下面的定義。

#define PHP_FUNCTION ZEND_FUNCTION

也就是說,這里用 ZEND_FUNCTION 替換了 PHP_FUNCTION 這個(gè)宏。所以,我們的定義就相當(dāng)于變成了這樣。

ZEND_FUNCTION(array_change_key_case)
{
    // TODO
}

我們繼續(xù)往下找,因?yàn)?,這里還是宏,我們并沒有看到我們希望看到的代碼。我們可以在 php-src/Zend/zend_API.h 中找到下面的定義。

#define ZEND_FN(name) zif_##name
#define ZEND_FUNCTION(name) ZEND_NAMED_FUNCTION(ZEND_FN(name))
#define ZEND_NAMED_FUNCTION(name) void name(INTERNAL_FUNCTION_PARAMETERS)

我們看到,在宏定義中,使用了另外的宏。不要怕,還是一個(gè)詞,替換。我們按照這樣的步驟來。(## 是一個(gè)連接符,它的作用是,是將它前面的與后面的,按照字符串的方式連接起來。

替換 ZEND_FUNCTION

ZEND_NAMED_FUNCTION(ZEND_FN(name))
{
    // TODO
}

替換 ZEND_FN

ZEND_NAMED_FUNCTION(zif_array_change_key_case)
{
    // TODO
}

替換 ZEND_NAMED_FUNCTION

void zif_array_change_key_case(INTERNAL_FUNCTION_PARAMETERS)
{
    // TODO
}

到這里,我們可以看到,這里已經(jīng)基本和我們熟悉的函數(shù)定義差不多了,不過,這還沒完,以為,這里還有宏,那就是 INTERNAL_FUNCTION_PARAMETERS。我們找到 php-src/Zend/zend.h,可以找到 INTERNAL_FUNCTION_PARAMETERS 的宏定義。

#define INTERNAL_FUNCTION_PARAMETERS zend_execute_data *execute_data, zval *return_value

好了,依然按照替換的原則,我們就可以將函數(shù)定義變成這樣了。

void zif_array_change_key_case(zend_execute_data *execute_data, zval *return_value)
{
    // TODO
}

看,整個(gè)函數(shù)的定義,已經(jīng)完全沒有宏了,這已經(jīng)是我們?cè)谑煜げ贿^的 C 語(yǔ)言函數(shù)的定義了。這就是
PHP_FUNCTION 的整個(gè)定義的過程。

execute_data 和 return_value

return_value,顧名思義,就是定義的 PHP 函數(shù)的返回值。而 execute_data,按照我的理解,就是 Zend 內(nèi)部的一個(gè)調(diào)用棧,而在執(zhí)行這個(gè)函數(shù)的時(shí)候,指向的是這個(gè)函數(shù)的棧幀。具體的細(xì)節(jié),暫時(shí)在這里先不考慮,有興趣的同學(xué)可以來這里看一下。深入理解 PHP 內(nèi)核

后記

我始終認(rèn)為,對(duì)于一個(gè) PHPer 來說,C 語(yǔ)言是一項(xiàng)必不可少的技能。理解 PHP 的內(nèi)核,對(duì)于我們編寫出高質(zhì)量的代碼,起到了關(guān)鍵的作用。所以,我現(xiàn)在開始研究 PHP 的源碼實(shí)現(xiàn)了。我希望我能通過這些文章,記錄下我理解源碼的瞬間,也希望我的文章能讓更多的 PHPer,進(jìn)入到 PHP 內(nèi)核的世界。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/25592.html

相關(guān)文章

  • 每日一個(gè) php 函數(shù)——array_change_key_case

    摘要:關(guān)于宏熟悉擴(kuò)展開發(fā)的同學(xué)應(yīng)該都知道,這個(gè)宏,是定義一個(gè)函數(shù)用的,參數(shù)就是函數(shù)的函數(shù)名。關(guān)于這個(gè)宏,有興趣的可以去看看源碼,它其實(shí)是將替換成了,這樣的一個(gè)函數(shù)定義。上面的幾個(gè)宏,是為了檢查并獲取傳參進(jìn)函數(shù)的變量。 因?yàn)橐呀?jīng)有文檔了,可能有些人覺得我寫這個(gè)有些多余了??墒遣⒉皇敲恳粋€(gè) PHPer 都會(huì)好好地去閱讀文檔,自然有一些函數(shù)可能都沒有聽說過(很不幸我也是這其中的一員)。我也希望能通...

    awkj 評(píng)論0 收藏0
  • PHP生命周期

    摘要:結(jié)算處理順利運(yùn)行完文件用戶主動(dòng)致命回收程序釋放掉這次請(qǐng)求使用過的所有東西包括變量表的所有變量所有在這次請(qǐng)求中申請(qǐng)的內(nèi)存等等請(qǐng)確保文件可寫,否則會(huì)莫名崩潰讓我們看看是不是每次請(qǐng)求結(jié)束都會(huì)在這個(gè)文件里追加數(shù)據(jù)通知自己要的時(shí)候,便進(jìn)入俗稱階段。 /* * PHP生命周期 * PHP程序的啟動(dòng) * 前置初始化(Apache或Nginx相關(guān)操作) * ...

    sushi 評(píng)論0 收藏0
  • PHP 源碼探秘 - 為什么 trim 會(huì)導(dǎo)致亂碼

    摘要:我的博客運(yùn)行以下代碼互聯(lián)網(wǎng)產(chǎn)品我們可能以為會(huì)得到的結(jié)果是互聯(lián)網(wǎng)產(chǎn)品,實(shí)際結(jié)果是互聯(lián)網(wǎng)產(chǎn)。所以在執(zhí)行的時(shí)候,通過字節(jié)比對(duì),會(huì)將去掉,導(dǎo)致了最后出現(xiàn)了亂碼。 我的博客 https://mengkang.net/1039.html 運(yùn)行以下代碼: $tag = 互聯(lián)網(wǎng)產(chǎn)品、; $text = rtrim($tag, 、); print_r($text); 我們可能以為會(huì)得到的結(jié)果是互聯(lián)網(wǎng)產(chǎn)品...

    xbynet 評(píng)論0 收藏0
  • (PHP7內(nèi)核剖析-11) 模塊擴(kuò)展

    摘要:編譯工具這個(gè)腳本主要生成了編譯需要的配置以及擴(kuò)展的基本結(jié)構(gòu)這個(gè)腳本主要是獲取的安裝信息用于生成文件編寫擴(kuò)展的基本步驟通過目錄下腳本生成擴(kuò)展的基本框架修改配置設(shè)置編譯配置參數(shù)設(shè)置擴(kuò)展的源文件依賴庫(kù)函數(shù)檢查等等定義一個(gè)這樣的編譯參數(shù) 1. 編譯工具 (a).ext_skel:這個(gè)腳本主要生成了編譯需要的配置以及擴(kuò)展的基本結(jié)構(gòu) (b).php-config:這個(gè)腳本主要是獲取PHP的安裝信息...

    gplane 評(píng)論0 收藏0
  • [譯] 理解 PHP 內(nèi)部函數(shù)的定義(給PHP開發(fā)者的PHP源碼-第二部分)

    摘要:文章來自原文歡迎來到給開發(fā)者的源碼系列的第二部分。是在內(nèi)部代表任意一個(gè)變量的定義。這種情況下函數(shù)會(huì)拋出警告,而此函數(shù)馬上返回會(huì)返回給的用戶層代碼。原因是,是少數(shù)通過而不是擴(kuò)展定義的函數(shù)。下一部分下一部分會(huì)再次發(fā)表在。 文章來自:http://www.hoohack.me/2016/02/10/understanding-phps-internal-function-definitio...

    hizengzeng 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<