Sophie

Sophie

distrib > Mageia > 4 > i586 > by-pkgid > f800694edefe91adea2624f711a41a2d > files > 8449

php-manual-en-5.5.7-1.mga4.noarch.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
 <head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <title>Introduction to Variables</title>

 </head>
 <body><div class="manualnavbar" style="text-align: center;">
 <div class="prev" style="text-align: left; float: left;"><a href="internals2.variables.html">Working with Variables</a></div>
 <div class="next" style="text-align: right; float: right;"><a href="internals2.variables.arrays.html">Working with Arrays</a></div>
 <div class="up"><a href="internals2.variables.html">Working with Variables</a></div>
 <div class="home"><a href="index.html">PHP Manual</a></div>
</div><hr /><div id="internals2.variables.intro" class="section">
  <h2 class="title">Introduction to Variables</h2>
  <p class="para">
   A good understanding of how variables are stored and manipulated is essential to becoming a <code class="code">Hacker</code>.
   The engine attempts to cover up the complexity of the concept of a variable that can be any type by 
   providing a uniform and intuitive set of macros for accessing the structures various fields. As the <code class="code">Hacker</code> works
   through this chapter, they should become comfortable with the terminology and concepts involved with Variables in PHP.
  </p>
  <blockquote class="note"><p><strong class="note">Note</strong>: 
   <p class="para">PHP is a dyanamic, loosely typed language, that uses copy-on-write and reference counting.</p>
  </p></blockquote>
  <p class="para">
   To clarify what exactly is meant by the statement above: PHP is a high level language, weak typing is implicit of the engines preference to
   convert, or coerce variables into the required type at execution type. Reference counting is the means by which the engine can deduce when a
   variable no longer has any references in the users code, and so is able to free the structures associated with the variable.
  </p>
  <p class="para">
   All variables in PHP are represented by one structure, the <code class="code">zval</code>:
  </p>
  <div class="example-contents screen">
<div class="cdata"><pre>
typedef struct _zval_struct {
    zvalue_value value;        /* variable value */
    zend_uint refcount__gc;    /* reference counter */
    zend_uchar type;           /* value type */
    zend_uchar is_ref__gc;     /* reference flag */
} zval;</pre></div>
  </div>
  <p class="para">
   The <code class="code">zval_value</code> is a union which can represent all types a variable may hold:
  </p>
  <div class="example-contents screen">
<div class="cdata"><pre>
typedef union _zvalue_value {
    long lval;                 /* long value */
    double dval;               /* double value */
    struct {                   
        char *val;
        int len;               /* this will always be set for strings */
    } str;                     /* string (always has length) */
    HashTable *ht;             /* an array */
    zend_object_value obj;     /* stores an object store handle, and handlers */
} zvalue_value;
</pre></div>
  </div>
  <p class="para">
   It should be clear from the structures above that a variable can be of one type, the variable data is represented by the appropriate field in the <code class="code">zval_value</code> union. The <code class="code">zval</code> itself holds the type, reference count and a flag to indicate if a variable is a reference.
  </p>
  <table id="internals2.variables.types.api" class="doctable table">
   <caption><strong>Native Type Constants</strong></caption>
   
    <thead>
     <tr>
      <th>Constant</th>
      <th>Mapping</th>
     </tr>

    </thead>

    <tbody class="tbody">
     <tr>
      <td><code class="code">IS_NULL</code></td>
      <td>no value is set in this case</td>
     </tr>

     
     <tr>
      <td><code class="code">IS_LONG</code></td>
      <td>lval</td>
     </tr>

     
     <tr>
      <td><code class="code">IS_DOUBLE</code></td>
      <td>dval</td>
     </tr>

     
     <tr>
      <td><code class="code">IS_BOOL</code></td>
      <td>lval</td>
     </tr>

     
     <tr>
      <td>IS_RESOURCE</td>
      <td>lval</td>
     </tr>

     
     <tr>
      <td>IS_STRING</td>
      <td>str</td>
     </tr>

     
     <tr>
      <td><code class="code">IS_ARRAY</code></td>
      <td>ht</td>
     </tr>

     
     <tr>
      <td><code class="code">IS_OBJECT</code></td>
      <td>obj</td>
     </tr>

     
    </tbody>
   
  </table>

  
  <blockquote class="note"><p><strong class="note">Note</strong>: 
   <p class="para">There are additional constants that help to identify internal types such as constant arrays and callable objects, their usage is outside the scope of this part of the documentation.</p>
  </p></blockquote>
  
  <p class="para">
   The following table defines the macros exposed by the engine for working with <code class="code">zval</code> values:
  </p>
  
  <table id="internals2.variables.zvals.api" class="doctable table">
   <caption><strong>Accessor Macros</strong></caption>
   
    <thead>
     <tr>
      <th>Prototype</th>
      <th>Accesses</th>
      <th>Description</th>
     </tr>

    </thead>

    <tbody class="tbody">
     <tr>
      <td><code class="code">zend_uchar Z_TYPE(zval zv)</code></td>
      <td>type</td>
      <td>returns the type of the <code class="code">value</code></td>
     </tr>

     
     <tr>
      <td><code class="code">long Z_LVAL(zval zv)</code></td>
      <td>value.lval</td>
      <td class="empty">&nbsp;</td>
     </tr>

     
     <tr>
      <td><code class="code">zend_bool Z_BVAL(zval zv)</code></td>
      <td>value.lval</td>
      <td>cast long <code class="code">value</code> to zend_bool</td>
     </tr>

     
     <tr>
      <td><code class="code">double Z_DVAL(zval zv)</code></td>
      <td>value.dval</td>
      <td class="empty">&nbsp;</td>
     </tr>

     
     <tr>
      <td><code class="code">long Z_RESVAL(zval zv)</code></td>
      <td>value.lval</td>
      <td>returns the resource list identifier for <code class="code">value</code></td>
     </tr>

     
     <tr>
      <td><code class="code">char* Z_STRVAL(zval zv)</code></td>
      <td>value.str.val</td>
      <td>return the string <code class="code">value</code></td>
     </tr>

     
     <tr>
      <td><code class="code">int Z_STRLEN(zval zv)</code></td>
      <td>value.str.len</td>
      <td>return the length of the string <code class="code">value</code></td>
     </tr>

     
     <tr>
      <td><code class="code">HashTable* Z_ARRVAL(zval zv)</code></td>
      <td>value.ht</td>
      <td>return the HashTable (array) <code class="code">value</code></td>
     </tr>

     
     <tr>
      <td><code class="code">zend_object_value Z_OBJVAL(zval zv)</code></td>
      <td>value.obj</td>
      <td>returns object <code class="code">value</code></td>
     </tr>

     
     <tr>
      <td><code class="code">uint Z_OBJ_HANDLE(zval zv)</code></td>
      <td>value.obj.handle</td>
      <td>returns the object handle for object <code class="code">value</code></td>
     </tr>

     
     <tr>
      <td><code class="code">zend_object_handlers* Z_OBJ_HT_P(zval zv)</code></td>
      <td>value.obj.handlers</td>
      <td>returns the handler table for object <code class="code">value</code></td>
     </tr>

     
     <tr>
      <td><code class="code">zend_class_entry* Z_OBJCE(zval zv)</code></td>
      <td>value.obj</td>
      <td>returns the class entry for object <code class="code">value</code></td>
     </tr>

     
     <tr>
      <td><code class="code">HashTable* Z_OBJPROP(zval zv)</code></td>
      <td>value.obj</td>
      <td>returns the properties of object <code class="code">value</code></td>
     </tr>

     
     <tr>
      <td><code class="code">HashTable* Z_OBJPROP(zval zv)</code></td>
      <td>value.obj</td>
      <td>returns the properties of object <code class="code">value</code></td>
     </tr>

     
     <tr>
      <td><code class="code">HashTable* Z_OBJDEBUG(zval zv)</code></td>
      <td>value.obj</td>
      <td>if an object has the get_debug_info handler set, it is called, else Z_OBJPROP is called</td>
     </tr>

     
    </tbody>
   
  </table>

  
  
  <p class="para">Please check the <a href="features.gc.refcounting-basics.html" class="xref">Reference Counting Basics</a> chapter for details how reference counting and references work in detail.</p>
  
  <table id="internals2.variables.refcounts.api" class="doctable table">
   <caption><strong>Reference Count Manipulation</strong></caption>
   
    <thead>
     <tr>
      <th>Prototype</th>
      <th>Description</th>
     </tr>

    </thead>

    
    <tbody class="tbody">
     <tr>
      <td><code class="code">zend_uint Z_REFCOUNT(zval zv)</code></td>
      <td>returns the reference count of the <code class="code">value</code></td>
     </tr>

     
     <tr>
      <td><code class="code">zend_uint Z_SET_REFCOUNT(zval zv)</code></td>
      <td>sets the reference count of the <code class="code">value</code>, returning it</td>
     </tr>

     
     <tr>
      <td><code class="code">zend_uint Z_ADDREF(zval zv)</code></td>
      <td>pre-increments the reference count of <code class="code">value</code>, returning it</td>
     </tr>

     
     <tr>
      <td><code class="code">zend_uint Z_DELREF(zval zv)</code></td>
      <td>pre-decrements the reference count of <code class="code">value</code>, returning it</td>
     </tr>

     
     <tr>
      <td><code class="code">zend_bool Z_ISREF(zval zv)</code></td>
      <td>tells if the zval is a reference</td>
     </tr>

     
     <tr>
      <td><code class="code">void Z_UNSET_ISREF(zval zv)</code></td>
      <td>set is_ref__gc to 0</td>
     </tr>

     
     <tr>
      <td><code class="code">void Z_SET_ISREF(zval zv)</code></td>
      <td>set is_ref__gc to 1</td>
     </tr>

     
     <tr>
      <td><code class="code">void Z_SET_ISREF_TO(zval zv, zend_uchar to)</code></td>
      <td>set is_ref__gc to <code class="code">to</code></td>
     </tr>

     
    </tbody>
   
  </table>

  
  <blockquote class="note"><p><strong class="note">Note</strong>: 
   <p class="para">The Z_* macros above all take a zval, they are all defined again suffixed with _P to take a pointer to a zval, for example <code class="code">zend_uchar Z_TYPE_P(zval* pzv)</code>, and again suffixed with _PP to take a pointer to a pointer to a zval, for example <code class="code">zend_uchar Z_TYPE_PP(zval** ppzv)</code></p>
  </p></blockquote>
  
  <table id="internals2.variables.general.api" class="doctable table">
   <caption><strong>Creation, Destruction, Separation and Copying</strong></caption>
   
    <thead>
     <tr>
      <th>Prototype</th>
      <th>Description</th>
     </tr>

    </thead>

    
    <tbody class="tbody">
     <tr>
      <td><code class="code">ALLOC_ZVAL(zval* pzval)</code></td>
      <td>emallocs <code class="code">pzval</code></td>
     </tr>

     
     <tr>
      <td><code class="code">ALLOC_INIT_ZVAL(zval* pzval)</code></td>
      <td>emallocs <code class="code">pzval</code>, and points <code class="code">pzval</code> at a null typed zval for sanity</td>
     </tr>

     
     <tr>
      <td><code class="code">MAKE_STD_ZVAL(zval* pzval)</code></td>
      <td>emallocs <code class="code">pzval</code>, setting the refcount to <code class="code">1</code></td>
     </tr>

     
     <tr>
      <td><code class="code">ZVAL_COPY_VALUE(zval* dst, zval* src)</code></td>
      <td>sets the value and type of <code class="code">dst</code> from the value and type of <code class="code">src</code></td>
     </tr>

     
     <tr>
      <td><code class="code">INIT_PZVAL_COPY(zval* dst, zval*dst) </code></td>
      <td>performs ZVAL_COPY_VALUE, setting refcount of <code class="code">dst</code> to 1, and setting is_ref__gc to <code class="code">0</code></td>
     </tr>

     
     <tr>
      <td><code class="code">SEPARATE_ZVAL(zval** ppzval)</code></td>
      <td>if the refcount of <code class="code">ppzval</code> is &gt;1, redirects <code class="code">*ppzval</code> to a newly emalloc&#039;d, copied, and constructed zval of the same type and value</td>
     </tr>

     
     <tr>
      <td><code class="code">SEPARATE_ZVAL_IF_NOT_REF(zval** ppzval)</code></td>
      <td>if <code class="code">*ppzval</code> is not a reference, will perform SEPARATE_ZVAL on <code class="code">ppzval</code></td>
     </tr>

     
     <tr>
      <td><code class="code">SEPARATE_ZVAL_TO_MAKE_IS_REF(zval** ppzval)</code></td>
      <td>if <code class="code">*ppzval</code> is not a reference, performs SEPARATE_ZVAL then Z_SET_ISREF_PP on <code class="code">ppzval</code></td>
     </tr>

     
     <tr>
      <td><code class="code">COPY_PZVAL_TO_ZVAL(zval dst, zval** src)</code></td>
      <td>results in <code class="code">dst</code> being a copy of <code class="code">src</code> without affecting the refcount of <code class="code">src</code></td>
     </tr>

     
     <tr>
      <td><code class="code">MAKE_COPY_ZVAL(zval** src, zval* dst)</code></td>
      <td>performs INIT_PZVAL_COPY, then zval_copy_ctor on the new zval</td>
     </tr>

     
     <tr>
      <td><code class="code">void zval_copy_ctor(zval** pzval)</code></td>
      <td>performs maintenance of reference counts, used widely throughout the engine</td>
     </tr>

     
     <tr>
      <td><code class="code">void zval_ptr_dtor(zval* pzval)</code></td>
      <td>decrements the refcount for the variable, if no refcounts remain the variable is destroyed</td>
     </tr>

     
     <tr>
      <td><code class="code">FREE_ZVAL(zval* pzval)</code></td>
      <td>efrees <code class="code">pzval</code></td>
     </tr>

     
    </tbody>
   
  </table>

  
  <blockquote class="note"><p><strong class="note">Note</strong>: 
   <p class="para">Objects and Resources have a reference count as part of their respective structures, when zval_ptr_dtor is called on either, their appropriate del_ref method is executed. See Working with Objects and Working with Resources for more information.</p>
  </p></blockquote>
  
  <p class="para">If the <code class="code">Hacker</code> only has room to remember two more functions, they should be <code class="code">zval_copy_ctor</code> and <code class="code">zval_ptr_dtor</code>, these are at the basis of the engines reference counting mechanisms and it is important to note that <code class="code">zval_copy_ctor</code> does not actually result in any copying occuring under normal circumstances, it simply increases the reference count. By the same token, <code class="code">zval_ptr_dtor</code> only really destroys a variable when there are no references remaining to it and the refcount is at 0.</p>
  
  <p class="para">PHP is weakly typed, as such the engine provides API functions for converting variables from one type to another.</p>
  
  <table id="internals2.variables.conversion.api" class="doctable table">
   <caption><strong>Type Conversion</strong></caption>
   
    <thead>
     <tr>
      <th>Prototype</th>
     </tr>

    </thead>

    <tbody class="tbody">
     
     <tr>
      <td><code class="code">void convert_to_long(zval* pzval)</code></td>
     </tr>

     
     <tr>
      <td><code class="code">void convert_to_double(zval* pzval)</code></td>
     </tr>

     
     <tr>
      <td><code class="code">void convert_to_long_base(zval* pzval, int base)</code></td>
     </tr>

     
     <tr>
      <td><code class="code">void convert_to_null(zval* pzval)</code></td>
     </tr>

     
     <tr>
      <td><code class="code">void convert_to_boolean(zval* pzval)</code></td>
     </tr>

     
     <tr>
      <td><code class="code">void convert_to_array(zval* pzval)</code></td>
     </tr>

     
     <tr>
      <td><code class="code">void convert_to_object(zval* pzval)</code></td>
     </tr>

     
     <tr>
      <td><code class="code">void convert_object_to_type(zval* pzval, convert_func_t converter)</code></td>
     </tr>

     
    </tbody>
   
  </table>

  
  <blockquote class="note"><p><strong class="note">Note</strong>: 
   <p class="para"><code class="code">convert_func_t</code> functions should have the prototype <code class="code">(void) (zval* pzval)</code></p>
  </p></blockquote>
  
  <p class="para">By now you should have a good understanding of: the types that are native to the engine, how to detect types and read zval values, how to manipulate refcounts, and other zval flags</p>
  
 </div><hr /><div class="manualnavbar" style="text-align: center;">
 <div class="prev" style="text-align: left; float: left;"><a href="internals2.variables.html">Working with Variables</a></div>
 <div class="next" style="text-align: right; float: right;"><a href="internals2.variables.arrays.html">Working with Arrays</a></div>
 <div class="up"><a href="internals2.variables.html">Working with Variables</a></div>
 <div class="home"><a href="index.html">PHP Manual</a></div>
</div></body></html>