Метка: zval

  • Анатомия zval: Основные компоненты (PHP 7+)

    В этой статье мы детально разберём структуру zval в современных версиях PHP, начиная с революционного PHP 7. Вы узнаете, как организовано хранение переменных на низком уровне и какие оптимизации были внедрены.

    2.1. Основные компоненты zval

    Структура _zval_struct

    struct _zval_struct {
        zend_value value;    // Основное значение (64 бита)
        union {
            struct {
                zend_uchar type;         // Тип данных (IS_LONG, IS_STRING и др.)
                zend_uchar type_flags;    // Флаги поведения типа
                zend_uchar const_flags;   // Флаги константности
                zend_uchar reserved;      // Зарезервировано
            } v;
            uint32_t type_info;           // Альтернативное представление
        } u1;                            // 32 бита
        union u2 {                       // 32 бита (служебные данные)
            uint32_t next;               // Для управления хеш-таблицами
            uint32_t cache_slot;         // Кеширование
            uint32_t lineno;             // Номер строки (для ошибок)
            uint32_t num_args;           // Количество аргументов
            uint32_t fe_pos;             // Позиция в foreach
            // ... другие служебные поля
        };
    }; // Всего 16 байт

    1. Компонент value (zend_value)

    ТипПолеРазмерОписание
    Целоеlval64 битаДля типов IS_LONG, IS_BOOL
    Дробноеdval64 битаДля IS_DOUBLE
    Указательstr64 битаДля строк (IS_STRING)
    Указательarr64 битаДля массивов (IS_ARRAY)

    2. Компонент u1 (метаданные типа)

    • type — определяет базовый тип данных (IS_LONG, IS_STRING и др.)
    • type_flags — дополнительные флаги поведения:
      • IS_TYPE_REFCOUNTED (требует подсчета ссылок)
      • IS_TYPE_COPYABLE (поддерживает Copy-On-Write)
      • IS_TYPE_IMMUTABLE (неизменяемый тип)
    • const_flags — флаги константности

    3. Компонент u2 (служебные данные)

    Этот компонент используется для различных оптимизаций:

    • next — связь элементов в хеш-таблицах
    • cache_slot — кеширование для быстрого доступа
    • lineno — отладка (номер строки в исходном коде)
    • num_args — информация о вызовах функций

    Практический пример

    // Создание zval с целым числом
    zval my_zval;
    ZVAL_LONG(&my_zval, 42);
    
    // Доступ к данным
    if (Z_TYPE(my_zval) == IS_LONG) {
        zend_long value = Z_LVAL(my_zval); // 42
        php_printf("Значение: %ld\n", value);
    }

    Продолжение следует в следующей статье цикла…

  • Введение в устройство zval: фундамент обработки данных в PHP

    Zval (Zend value) — фундаментальная структура данных в ядре PHP, ответственная за хранение и обработку всех переменных. В этой статье мы исследуем её эволюцию, современную реализацию и практическое значение для разработчиков.

    Историческая эволюция zval

    PHP 5: Первое поколение

    • 24-байтовая структура
    • Универсальный подсчет ссылок
    • Высокие накладные расходы

    PHP 7: Революция

    • 16 байт (экономия 33%)
    • Разделение value/type
    • Оптимизация скаляров

    PHP 8: Совершенство

    • Дополнительные оптимизации
    • Интеграция с JIT
    • Улучшенные хеш-таблицы

    Структура zval в PHP 8

    struct _zval_struct {
        zend_value value;    // 64-битное значение
        union {
            struct {
                zend_uchar type;        // Тип данных
                zend_uchar type_flags;  // Флаги поведения
                zend_uchar const_flags; // Константность
                zend_uchar reserved;    // Выравнивание
            } v;
            uint32_t type_info;
        } u1;
        union u2 {
            uint32_t next;
            // ... служебные поля
        };
    }; // Всего 16 байт

    Ключевые оптимизации

    • Отказ от refcount для скаляров — целые числа и булевы значения больше не используют подсчет ссылок
    • Copy-On-Write — сложные структуры копируются только при модификации
    • Встроенное кеширование хешей — ускорение операций сравнения строк
    • Оптимизированные хеш-таблицы — быстрый доступ к элементам массивов

    Практическое применение для разработчиков и авторов расширений

    • Оптимизация потребления памяти
    • Эффективная работа с переменными
    • Понимание поведения типов

    Пример:

    // Создание строки в расширении
    zend_string *str = zend_string_init("test", 4, 0);
    zval zv;
    ZVAL_STR(&zv, str);