<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # 12.4 PHP擴展中的全局變量 這一章,我們將學會如何在PHP擴展中使用全局變量。 在擴展中定義全局變量 首先,我們需要在擴展的頭文件中(默認是php_*.h)中定義所有的全局變量。舉個例子,比如我們要定義一個無符號的long類型的全局變量,我們可以這樣定義: ````c ZEND_BEGIN_MODULE_GLOBALS(sample4) unsigned long counter; ZEND_END_MODULE_GLOBALS(sample4) ```` 用ZEND_BEGIN_MODULE_GLOBALS和ZEND_END_MODULE_GLOBALS宏將定義的全局變量包起來。將上例中的宏展開后,是下面這個樣子: ````c typedef struct _zend_sample4_globals { unsigned long counter; } zend_sample4_globals; ```` 如果你還有其他的全局變量需要定義,只需加在兩個宏之間就可以了。接下來我們該在simple4.c中聲明我們在頭文件中定義的這些全局變量了: ````c ZEND_DECLARE_MODULE_GLOBALS(sample4); ```` 這個宏的內部實現取決于是否啟用了線程安全,在非線程安全的環境下,如:Apache1,Apache2-prefork, CGI,CLI...會使用zend_sample4_globals結構來定義 全局變量: ````c zend_sample4_globals sample4_globals; ```` 我們可以直接通過sample4_globals.counter來獲取計數器的值。在線程安全的版本中,另一種方法是聲明一個整數: ````c int sample4_globals_id; ```` 填充這個ID就等于定義了擴展中的全局變量。根據其定義的信息,將為每個新線程的獨立存儲空間分配內存塊。我們可以在MINIT中這樣定義: ````c #ifdef ZTS ts_allocate_id( &sample4_globals_id, sizeof(zend_sample4_globals), NULL, NULL); #endif ```` 有一點需要注意這種方法需要包裹在#ifdef中,以防止它在沒有啟動Zend Thread Safety(ZTS)時執行。因為sample4_globals_id只能在多線程環境中使用。非線程 的版本用我們在前面提到的sample4_globals來聲明全局變量。 線程中的初始化和關閉 在非線程的環境中,會將一個zend_sample4_globals結構的副本保存在指定進程中。你可以指定他的默認值,或者在MINIT或者RINIT中分配資源來初始化它。要記得 在對應的MSHUTDOWN或者RSHUTDOWN中及時釋放這些資源。 然而在線程版本中,一個新的結構會在一個新線程spun的時候被分配。為了知道怎樣初始化和關閉擴展中的全局變量,需要向ZE引擎提供回調函數。在前面我們在調用 ts_allocate_id()的時候是是以NULL來作為這個值的,接下來我們添加2個一會需要在MINIT調用的方法: ````c static void php_sample4_globals_ctor(zend_sample4_globals *sample4_globals TSRMLS_DC) { /* Initialize a new zend_sample4_globals struct * During thread spin-up */ sample4_globals->counter = 0; } static void php_sample4_globals_dtor(zend_sample4_globals *sample4_globals TSRMLS_DC) { /* Any resources allocated during initialization * May be freed here */ } ```` 我們在啟用和關閉的時候調用它們: ````c PHP_MINIT_FUNCTION(sample4) { REGISTER_STRING_CONSTANT("SAMPLE4_VERSION", PHP_SAMPLE4_EXTVER, CONST_CS | CONST_PERSISTENT); #ifdef ZTS ts_allocate_id(&sample4_globals_id, sizeof(zend_sample4_globals), (ts_allocate_ctor)php_sample4_globals_ctor, (ts_allocate_dtor)php_sample4_globals_dtor); #else php_sample4_globals_ctor(&sample4_globals TSRMLS_CC); #endif return SUCCESS; } PHP_MSHUTDOWN_FUNCTION(sample4) { #ifndef ZTS php_sample4_globals_dtor(&sample4_globals TSRMLS_CC); #endif return SUCCESS; } ```` 現在我們已經知道如何在擴展中創建全局變量了,在不是ZTS的環境中,使用它們很簡單,我們還來看前面定義的那個計數器的遞增功能如何實現: ````c PHP_FUNCTION(sample4_counter) { RETURN_LONG(++sample4_globals.counter); } ```` 是不是看起來很簡單,但是,在線程版本中將無法正常工作。那么我們來看看怎么在線程環境中完成這個功能吧: ````c PHP_FUNCTION(sample4_counter) { #ifdef ZTS RETURN_LONG(++TSRMG(sample4_globals_id, \ zend_sample4_globals*, counter)); #else /* non-ZTS */ RETURN_LONG(++sample4_globals.counter); #endif } ```` 看起來很丑對嗎?想象一下,在你的整個代碼庫中,這些IFDEF指令在每一個線程安全的全局訪問時穿插。它會看起來比Perl更糟糕!這就是為什么所有 的核心擴展,都有使用一個額外的宏觀層抽象這種情況。我們可以在php_sample4.h中找到下面這段代碼: ````c #ifdef ZTS #include "TSRM.h" #define SAMPLE4_G(v) TSRMG(sample4_globals_id, zend_sample4_globals*, v) #else #define SAMPLE4_G(v) (sample4_globals.v) #endif ```` 使用它們會讓你的方法看起來更簡潔: ````c PHP_FUNCTION(sample4_counter) { RETURN_LONG(++SAMPLE4_G(counter)); } ```` 看到*G()這樣的宏是不是有種似曾相識的感覺?也許以前你看到過EG()、CG()等宏,了解他們會讓你對PHP的了解更深一步: Accessor Macro | Associated Data ------------- | ------------- EG() | 這個宏可以用來訪問符號表,函數,資源信息和常量。 CG() | 用來訪問核心全局變量。 PG() | PHP全局變量。我們知道php.ini會映射一個或者多個PHP全局結構。舉幾個使用這個宏的例子:PG(register_globals), PG(safe_mode), PG(memory_limit) FG() | 文件全局變量。大多數文件I/O或相關的全局變量的數據流都塞進標準擴展出口結構。 ## links * [目錄](<preface.md>) * 12.3 [常量](<12.3.md>) * 12.5 [PHP語言中的超級全局變量](<12.5.md>)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看