W3docs

extract()

PHP extract() импортирует ключи ассоциативного массива как переменные в текущую таблицу символов. Синтаксис, флаги и примеры.

Что такое extract() в PHP?

extract() — встроенная функция PHP, которая импортирует элементы ассоциативного массива в текущую таблицу символов, превращая каждый ключ в переменную со значением соответствующего элемента массива. Она является обратной к compact(), которая строит массив из существующих переменных.

Её сигнатура:

extract(array &$array, int $flags = EXTR_OVERWRITE, string $prefix = ""): int
  • $array — исходный массив. Переменными становятся только строковые ключи, являющиеся допустимыми именами переменных PHP. Числовые ключи пропускаются, если не используется флаг с префиксом.
  • $flags — управляет обработкой конфликтов имён с существующими переменными (см. Флаги и поведение).
  • $prefix — строка, добавляемая к именам переменных при использовании флага с префиксом.

Функция возвращает количество успешно импортированных переменных.

Как использовать extract() в PHP

Начните с ассоциативного массива, ключи которого — это нужные имена переменных:

$person = [
    'name'  => 'John Doe',
    'age'   => 30,
    'email' => '[email protected]',
];

extract($person);

echo $name;   // John Doe
echo $age;    // 30
echo $email;  // [email protected]

После extract($person) в текущей области видимости создаются три переменные — $name, $age и $email, — каждая содержит значение соответствующего ключа.

Извлечение только некоторых ключей

По умолчанию extract() создаёт переменные для каждого ключа. Чтобы импортировать подмножество, сначала отфильтруйте массив с помощью array_intersect_key() и array_flip():

$wanted = ['name', 'email'];
$count = extract(array_intersect_key($person, array_flip($wanted)));

echo $count;  // 2
echo $name;   // John Doe
echo $email;  // [email protected]
// $age is NOT created

array_flip($wanted) преобразует ['name', 'email'] в ['name' => 0, 'email' => 1], а array_intersect_key() оставляет только эти ключи из $person, поэтому извлекаются лишь $name и $email.

Флаги и поведение

Второй параметр управляет тем, как обрабатываются существующие переменные при конфликте имён ключа с уже существующей переменной. Наиболее распространённые флаги:

ФлагПоведение
EXTR_OVERWRITEПо умолчанию. Перезаписывает существующую переменную с тем же именем.
EXTR_SKIPОставляет существующую переменную нетронутой и пропускает этот ключ.
EXTR_PREFIX_SAMEПри конфликте добавляет к новой переменной $prefix.
EXTR_PREFIX_ALLДобавляет $prefix ко всем импортируемым переменным.
EXTR_REFSИмпортирует переменные как ссылки на элементы массива.

Сравните EXTR_OVERWRITE (по умолчанию) с EXTR_SKIP:

$name = 'Existing Name';
$data = ['name' => 'New Name'];

extract($data);             // default: overwrites
echo $name;                 // New Name

$name = 'Existing Name';
extract($data, EXTR_SKIP);  // keep what's already set
echo $name;                 // Existing Name

Используйте EXTR_PREFIX_ALL, чтобы добавить пространство имён ко всем переменным и полностью избежать конфликтов:

$data = ['name' => 'John', 'age' => 30];
extract($data, EXTR_PREFIX_ALL, 'user');

echo $user_name;  // John
echo $user_age;   // 30

Предупреждение о безопасности

Поскольку extract() динамически создаёт переменные из ключей, передача ей недоверенных данных может привести к перезаписи существующих переменных — в том числе критически важных или суперглобальных, таких как $_GET, $_POST и $_SESSION. Классическая уязвимость — extract($_GET), которая позволяет злоумышленнику установить любую переменную в вашем скрипте через строку запроса:

$is_admin = false;
extract($_GET);          // ?is_admin=1 now makes $is_admin truthy — dangerous!

Никогда не вызывайте extract() непосредственно с данными запроса. Если это необходимо, передавайте EXTR_SKIP, чтобы существующие переменные не могли быть перезаписаны, или добавляйте в белый список нужные ключи с помощью array_intersect_key(), как показано выше.

Когда использовать extract()

extract() хорошо подходит для узких, контролируемых ситуаций:

  • Рендеринг шаблонов — движок представлений извлекает известный массив данных в локальные переменные непосредственно перед подключением шаблона, чтобы в нём можно было писать $title вместо $data['title'].
  • Распаковка конфигурации — преобразование небольшого доверенного конфигурационного массива в именованные переменные в начале скрипта.

В большинстве случаев явное присваивание понятнее и безопаснее extract(), потому что читатель сразу видит, какие именно переменные появляются в области видимости. Используйте функцию только тогда, когда ключи надёжны и выигрыш в читаемости очевиден.

Итоги

extract() импортирует ключи ассоциативного массива как переменные в текущей области видимости и возвращает количество созданных переменных. Поведение по умолчанию EXTR_OVERWRITE делает функцию мощной, но рискованной: всегда фильтруйте входные данные или используйте EXTR_SKIP с недоверенными данными. Чтобы сделать обратное — построить массив из переменных — используйте compact().

Практика

Практика
Какова функциональность функции extract() в PHP?
Какова функциональность функции extract() в PHP?
Was this page helpful?