Intro

For working with variables in PHP's core you have to learn about different fundamental concepts used in PHP. Firstly PHP is a dynamic and weak typed language. Secondly PHP uses a copy on write mechanism with reference counting for memory handling. Please check the Reference Counting Basics chapter for details how reference counting and references work.

PHP variables, in general, consist out of two things: The label, which might, for instance, be an entry in a symbol table, and the actual variable container. For the most parts of this manual we will focus on the variable container.

The variable container, in code called zval, is holding all data needed to handle the variable. This includes not only the actual value but also the current type, a counter counting the number of labels pointing to this container and a flag whether these labels should be treated as references or copies. In PHP 5.3 the relevant structures, which you can find in Zend/zend.h, look like this:

typedef struct _zval_struct zval;

typedef union _zvalue_value {
    long lval;                 /* long value */
    double dval;               /* double value */
    struct {                   /* string type */
        char *val;
        int len;
    } str;
    HashTable *ht;             /* hash table value */
    zend_object_value obj;
} zvalue_value;
 
struct _zval_struct {
    /* Variable information */
    zvalue_value value;        /* value */
    zend_uint refcount__gc;
    zend_uchar type;           /* active type */
    zend_uchar is_ref__gc;
};

In the zvalue_value one can find the internal representation for the different types the fields used should be clear from the names and comments - especially if one knows that PHP's arrays are infact hash tables. Nonetheless, knowing PHP's types one might miss a few: NULL, boolean and resources. For NULL we need no value, as NULL is the value of that type. For boolean and resource values PHP re-uses the value field. In the case of a boolean it holds either 0 for false or 1 for true. For resource-typed variables it holds the resource id.

Now the good message is that you don't have to know these things in detail as there are - like always in PHP - acces macros. The bad news is that there are many of them: There are macros to access any aspect of the zval and then, as one often deals with pointers to zvals and even pointers to pointers to zvals, for most of them there are shortcuts dereferencing these pointers. These macros are spread over Zend/zend.h, Zend/zend_operators.h and Zend/zend_API.h.