<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擴展中的全局變量 # 12.4 PHP擴展中的全局變量 這一章,我們將學會如何在PHP擴展中使用全局變量。 在擴展中定義全局變量 首先,我們需要在擴展的頭文件中(默認是php\_\*.h)中定義所有的全局變量。舉個例子,比如我們要定義一個無符號的long類型的全局變量,我們可以這樣定義: ``` ZEND_BEGIN_MODULE_GLOBALS(sample4) unsigned long counter; ZEND_END_MODULE_GLOBALS(sample4) ``` 用ZEND\_BEGIN\_MODULE\_GLOBALS和ZEND\_END\_MODULE\_GLOBALS宏將定義的全局變量包起來。將上例中的宏展開后,是下面這個樣子: ``` typedef struct _zend_sample4_globals { unsigned long counter; } zend_sample4_globals; ``` 如果你還有其他的全局變量需要定義,只需加在兩個宏之間就可以了。接下來我們該在simple4.c中聲明我們在頭文件中定義的這些全局變量了: ``` ZEND_DECLARE_MODULE_GLOBALS(sample4); ``` 這個宏的內部實現取決于是否啟用了線程安全,在非線程安全的環境下,如:Apache1,Apache2-prefork, CGI,CLI...會使用zend\_sample4\_globals結構來定義 全局變量: ``` zend_sample4_globals sample4_globals; ``` 我們可以直接通過sample4\_globals.counter來獲取計數器的值。在線程安全的版本中,另一種方法是聲明一個整數: ``` int sample4_globals_id; ``` 填充這個ID就等于定義了擴展中的全局變量。根據其定義的信息,將為每個新線程的獨立存儲空間分配內存塊。我們可以在MINIT中這樣定義: ``` #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調用的方法: ``` 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 */ } ``` 我們在啟用和關閉的時候調用它們: ``` 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的環境中,使用它們很簡單,我們還來看前面定義的那個計數器的遞增功能如何實現: ``` PHP_FUNCTION(sample4_counter) { RETURN_LONG(++sample4_globals.counter); } ``` 是不是看起來很簡單,但是,在線程版本中將無法正常工作。那么我們來看看怎么在線程環境中完成這個功能吧: ``` 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中找到下面這段代碼: ``` #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 ``` 使用它們會讓你的方法看起來更簡潔: ``` PHP_FUNCTION(sample4_counter) { RETURN_LONG(++SAMPLE4_G(counter)); } ``` 看到\*G()這樣的宏是不是有種似曾相識的感覺?也許以前你看到過EG()、CG()等宏,了解他們會讓你對PHP的了解更深一步: Accessor MacroAssociated DataEG()這個宏可以用來訪問符號表,函數,資源信息和常量。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.html) - 12.5 [PHP語言中的超級全局變量](12.5.html)
                  <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>

                              哎呀哎呀视频在线观看