PHP is known for being a server-side scripting language that is easy to adopt, thanks mostly to its low learning curve. One part of this low curve comes from the dynamically-typed nature that makes it possible to not bother too much about the internal types used when manipulating data. However, it is also interesting to focus on the internal representation of data, including the way that they are manipulated to gain CPU/memory usage or to produce better code, while making it clear what their intentions are or just for the curiosity of the reader.
Dynamically-typed means that there is no such thing as a “variable type” in PHP. It is the value and not the variable itself that has this notion of type. To understand this, let’s have a look at how PHP stores values (named internally “ZVAL”) in memory by looking at the underlying structure (Figure 1).
A ZVAL is a C structure composed of 4 properties:
- The type: a single byte explaining what the data type of the PHP variable is; which tells you how the value property of the ZVAL should be accessed. This is normally inspected when calling an is_*() function.
- The value: is the part of the ZVAL which contains what we already used to manipulate in PHP, it may contain an integer (a long), a floating point number, a string, an array, a resource, an object and so on.. This can be seen as a structure as well (composed of lval, dval, str, ht and obj), but since only one of those sub-components is used at a specific time (a PHP value can be an integer *or* a float *or* a string,… but not several types at the same time), the C language provides a special construct called a union, which optimizes the space usage of such a structure. Basically, it can be seen by all sub-components of the value that reference the same memory space, but depending on the sub-component used. The C language will know how and what to manipulate, all of those types not taking the same amount of bytes will not be manipulated.
- The refcount__gc: a counter of references that increases and decreases. It can tell how many PHP variable names point to the current ZVAL.
- The is_ref__gc: a flag telling the user if the variable is a reference. On 64 bits system, a ZVAL takes 24 bytes and 16 on 32 bits system. To learn more about the reference counting mechanism, I would suggest you to read the PHP manual entry which explains this very well under the “Garbage Collection” chapter.