Fading Coder

One Final Commit for the Last Sprint

Home > Tools > Content

Internal Implementation of Variables in PHP 7

Tools May 13 1

In PHP, variables consist of two components: the variable name and variable value. These correspond to zval and zend_value structures respectively. PHP manages variabel memory through reference counting, which in PHP 7 is tracked in zend_value rather than zval.

Variable Definition and Initialization

PHP variables are defined using the $ keyword:

$varName;
$varName = "initial value";

These operations involve two distinct steps: declaration and initialization.

Core Data Structures

zval Structure

typedef struct _zval_struct zval;

typedef union _zend_value {
    int64_t          long_val;     // Integer values
    double           double_val;   // Floating-point values
    zend_refcounted *ref_counted;
    zend_string     *string_ptr;   // String references
    zend_array      *array_ptr;    // Array references
    zend_object     *object_ptr;   // Object references
    zend_resource   *resource_ptr; // Resource handles
    zend_reference  *reference_ptr;// Reference types
    zend_ast_ref    *ast_ref;
    zval            *zval_ptr;
    void            *void_ptr;
    zend_class_entry *class_entry;
    zend_function   *function_ptr;
    struct {
        uint32_t word1;
        uint32_t word2;
    } double_word;
} zend_value;

struct _zval_struct {
    zend_value        stored_value;
    union {
        struct {
            ZEND_ENDIAN_LOHI_4(
                unsigned char type,
                unsigned char type_flags,
                unsigned char const_flags,
                unsigned char reserved)
        } detail;
        uint32_t type_data;
    } metadata;
    union {
        uint32_t     variable_flags;
        uint32_t     hash_next;
        uint32_t     cached_slot;
        uint32_t     line_number;
        uint32_t     argument_count;
        uint32_t     foreach_position;
        uint32_t     foreach_index;
    } auxiliary;
};

Data Type Constants

#define IS_UNDEFINED          0
#define IS_NULL               1
#define IS_FALSE              2
#define IS_TRUE               3
#define IS_LONG               4
#define IS_DOUBLE             5
#define IS_STRING             6
#define IS_ARRAY              7
#define IS_OBJECT             8
#define IS_RESOURCE           9
#define IS_REFERENCE          10
#define IS_CONSTANT           11
#define IS_CONSTANT_AST       12
#define _IS_BOOL              13
#define IS_CALLABLE           14
#define IS_INDIRECT           15
#define IS_POINTER            17

Scalar Types

Simple types including booleans, integers, doubles, and null values store their data directly within the zend_value union without additional memory allocations.

String Implementation

struct _zend_string {
    zend_refcounted_h refcount_header;
    uint64_t          hash_value;
    size_t            length;
    char              content[1];
};

Strings are categorized into several types based on their allocation method and lifecycle characteristics.

Array Implementation

Arrays are implemented as ordered hash tables:

typedef struct _zend_array HashTable;

struct _zend_array {
    zend_refcounted_h refcount_header;
    union {
        struct {
            ZEND_ENDIAN_LOHI_4(
                unsigned char flags,
                unsigned char apply_count,
                unsigned char iterator_count,
                unsigned char reserved)
        } detail;
        uint32_t flags;
    } metadata;
    uint32_t          table_mask;
    Bucket           *data_array;
    uint32_t          used_count;
    uint32_t          element_count;
    uint32_t          table_size;
    uint32_t          internal_pointer;
    int64_t           next_free_element;
    dtor_func_t       destructor_func;
};

Reference Implementation

References create a specialized structure:

struct _zend_reference {
    zend_refcounted_h refcount_header;
    zval              referenced_value;
};

Example reference behavior:

$original = "data string";
$reference = &$original;
$copy = $reference;

Memory Management

PHP employs reference counting with copy-on-write semantics for efficient memory management.

Reference Counting Mechanism

typedef struct _zend_refcounted_h {
    uint32_t         reference_count;
    union {
        struct {
            ZEND_ENDIAN_LOHI_3(
                unsigned char type,
                unsigned char flags,
                uint16_t      gc_data)
        } detail;
        uint32_t type_info;
    } metadata;
} zend_refcounted_h;

Not all data types utilize reference counting. Scalar types and interned strings employ direct value copying.

Copy-on-Write Semantics

When multiple variables reference the same value, modifications trigger a copy operation:

$first = [1, 2, 3];
$second = $first;
$second[] = 4; // Triggers copy operation

Garbage Collection

PHP utilizes a tracing garbage collector for circular references:

$circular = [];
$circular[] = &$circular;
unset($circular); // Creates collectable garbage

The garbage collector identifies and cleans up circular references that cannot be freed through simple reference counting.

Related Articles

Installing CocoaPods on macOS Catalina (10.15) Using a User-Managed Ruby

System Ruby on macOS 10.15 frequently fails to build native gems required by CocoaPods (for example, ffi), leading to errors like: ERROR: Failed to build gem native extension checking for ffi.h... no...

Resolve PhpStorm "Interpreter is not specified or invalid" on WAMP (Windows)

Symptom PhpStorm displays: "Interpreter is not specified or invalid. Press ‘Fix’ to edit your project configuration." This occurs when the IDE cannot locate a valid PHP CLI executable or when the debu...

Capturing Android Screenshots and Screen Recordings with ADB

Two practical ways to grab images and videos from an Android device: Mirror the phone display to a computer and use desktop tools for screenshots and GIFs Use ADB commands (no UI mirroring required)...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.