internals2.structure.globals.html

来自「php的帮助文档,涉及到PHP的案例和基本语法,以及实际应用内容」· HTML 代码 · 共 199 行

HTML
199
字号
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html> <head>  <title>Extension globals</title>  <meta http-equiv="content-type" content="text/html; charset=UTF-8"> </head> <body><div style="text-align: center;"> <div class="prev" style="text-align: left; float: left;"><a href="internals2.structure.modstruct.html">The zend_module structure</a></div> <div class="next" style="text-align: right; float: right;"><a href="internals2.structure.lifecycle.html">Life cycle of an extension</a></div> <div class="up"><a href="internals2.structure.html">Extension structure</a></div> <div class="home"><a href="index.html">PHP Manual</a></div></div><hr /><div id="internals2.structure.globals" class="sect1">  <h2 class="title">Extension globals</h2>  <div id="internals2.structure.globals.intro" class="sect2">   <h3 class="title">Introduction to globals in a PHP extension</h3>   <p class="simpara">    In a language such as C, a &quot;global&quot; variable is a variable that can be    accessed from any function without any extra declaration. These traditional    globals have a few drawbacks:   </p>   <ul class="itemizedlist">    <li class="listitem">     <span class="simpara">      Barring any special options passed to the compiler, a global varaible can      be accessed and changed by any piece of code anywhere in the program,      whether or not that code should be doing so.     </span>    </li>    <li class="listitem">     <span class="simpara">      A typical global variable is not thread safe.     </span>    </li>    <li class="listitem">     <span class="simpara">      The names of global variables are as global as the variables themselves.     </span>    </li>   </ul>   <p class="simpara">    A PHP extension&#039;s globals are more properly called the &quot;extension state&quot;,    since most modules must remember what they&#039;re doing between function calls.    The &quot;counter&quot; extension is a perfect example of this need: The basic    interface calls for a counter with a persistant value. A programmer new to    Zend and PHP might do something like this in <var class="filename">counter.c</var>    to store that value:   </p>   <div class="example" id="internals2.structure.globals.intro.wrong-way" name="internals2.structure.globals.intro.wrong-way">    <p><b>Example #1 The wrong way to store the basic counter interface&#039;s value</b></p>    <div class="example-contents"><div class="cdata"><pre>/* ... */static long basic_counter_value;/* ... */PHP_FUNCTION(counter_get){    RETURN_LONG(basic_counter_value);}</pre></div>    </div>   </div>   <p class="simpara">    On the surface this appears a viable solution, and indeed in a simple test    it would function correctly. However, there are a number of situations in    which more than one copy of PHP is running in the same thread, which means    more than one instance of the counter module. Suddenly these multiple    threads are sharing the same counter value, which is clearly undesireable.    Another problem shows itself when considering that another extension might    someday happen to have a global with the same name, and due to the rules of    C scoping, this has the potential to cause a compile failure, or worse, a    runtime error. Something more elaborate is needed, and so exists Zend&#039;s    support for threadsafe per-module globals.   </p>  </div>  <div id="internals2.structure.globals.declaring" class="sect2">   <h3 class="title">Declaring module globals</h3>      <p class="simpara">    Whether a module uses only a single global or dozens, they must be defined    in a structure, and that structure must be declared. There are some macros    that assist with doing so in a way that avoids name conflicts between    modules: <b>ZEND_BEGIN_MODULE_GLOBALS()</b>,    <b>ZEND_END_MODULE_GLOBALS()</b>, and    <b>ZEND_DECLARE_MODULE_GLOBALS()</b>. All three take as a    parameter the short name of the module, which in the case of the counter    module is simply <i>&quot;counter&quot;</i>. Here is the global structure    declaration from <var class="filename">php_counter.h</var>:   </p>   <div class="example" id="internals2.structure.globals.declaring.doth" name="internals2.structure.globals.declaring.doth">    <p><b>Example #2 The counter module&#039;s globals</b></p>    <div class="example-contents"><div class="cdata"><pre>ZEND_BEGIN_MODULE_GLOBALS(counter)    long        basic_counter_value;ZEND_END_MODULE_GLOBALS(counter)</pre></div>    </div>   </div>   <p class="simpara">    And this is the declaration from <var class="filename">counter.c</var>:   </p>   <div class="example" id="internals2.structure.globals.declaring.dotc" name="internals2.structure.globals.declaring.dotc">    <p><b>Example #3 The counter module&#039;s global structure declaration</b></p>    <div class="example-contents"><div class="cdata"><pre>ZEND_DECLARE_MODULE_GLOBALS(counter)</pre></div>    </div>   </div>    </div>    <div id="internals2.structure.globals.using" class="sect2">   <h3 class="title">Accessing module globals</h3>      <p class="simpara">    As discussed above, per-module globals are declared inside a C structure    whose name is obscured by Zend macros. As a result, the ideal way to access    members of this structure is by the use of further macros. Accordingly, most    if not all extensions which have globals have a declaration like this    somewhere in their header file:   </p>   <div class="example" id="internals2.structure.globals.using.accessor" name="internals2.structure.globals.using.accessor">    <p><b>Example #4 Accessor macros for per-module globals</b></p>    <div class="example-contents"><div class="cdata"><pre>#ifdef ZTS#define COUNTER_G(v) TSRMG(counter_globals_id, zend_counter_globals *, v)#else#define COUNTER_G(v) (counter_globals.v)#endif</pre></div>    </div>   </div>   <blockquote><p><b class="note">Note</b>:     <span class="simpara">     This could have been generalized into a macro of its own by the Zend API,     but as of PHP 5.3 (and PHP 6 at the time of this writing), that hasn&#039;t     happened. The global accessor construct is written into the header by     <strong class="command">ext_skel</strong> and thus is generally left alone by extension     writers, unless they wish to change the name of the accessor macro.    </span>   </p></blockquote>   <blockquote><p><b class="note">Note</b>:     <span class="simpara">     <b><tt>COUNTER_G</tt></b> was the name given to the macro by     <strong class="command">ext_skel</strong>, but it&#039;s not necessary for it to have that     name and could just as easily be called <i>FOO</i> instead.    </span>   </p></blockquote>   <p class="simpara">    Any code in the counter extension that accesses a global must thus wrap it    in the macro <b><tt>COUNTER_G</tt></b>.   </p>   <div class="warning"><b class="warning">Warning</b>    <p class="simpara">     Any function which accesses globals must either be declared by Zend macros,     have <b><tt>TSRMLS_DC</tt></b> as its last argument, or call the macro     <b><tt>TSRMLS_FETCH</tt></b> before accessing the globals. See     the TSRM documentation for     more information.    </p>   </div>    </div> </div><hr /><div style="text-align: center;"> <div class="prev" style="text-align: left; float: left;"><a href="internals2.structure.modstruct.html">The zend_module structure</a></div> <div class="next" style="text-align: right; float: right;"><a href="internals2.structure.lifecycle.html">Life cycle of an extension</a></div> <div class="up"><a href="internals2.structure.html">Extension structure</a></div> <div class="home"><a href="index.html">PHP Manual</a></div></div></body></html>

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?