(PHP 4, PHP 5, PHP 7)
extract — Импортирует переменные из массива в текущую таблицу символов
&$array
[, int $flags
= EXTR_OVERWRITE
[, string $prefix
= NULL
]] )Импортирует переменные из массива в текущую таблицу символов.
Каждый ключ проверяется на предмет корректного имени переменной. Также проверяются совпадения с существующими переменными в символьной таблице.
array
Ассоциативный массив. Эта функция рассматривает ключи массива
в качестве имен переменных, а их значения - в качестве значений
этих переменных. Для каждой пары ключ/значение будет создана
переменная в текущей таблице символов, в соответствии с
параметрами flags
и
prefix
.
Вы должны использовать ассоциативный массив, использование
числовых массивов не приведёт ни к каким результатам,
если вы не используете EXTR_PREFIX_ALL
или EXTR_PREFIX_INVALID
.
flags
Параметр flags
определяет способ
трактования неправильных/числовых ключей и коллизий. Он может
принимать следующие значения:
EXTR_OVERWRITE
EXTR_SKIP
EXTR_PREFIX_SAME
prefix
.
EXTR_PREFIX_ALL
prefix
ко всем именам переменных.
EXTR_PREFIX_INVALID
prefix
только к
некорректным/числовым именам переменных.
EXTR_IF_EXISTS
EXTR_PREFIX_IF_EXISTS
EXTR_REFS
array
.
Вы можете использовать этот флаг отдельно или
комбинировать его с другими значениями
flags
с помощью побитового 'или'.
Если flags
не указан, он
трактуется как EXTR_OVERWRITE
.
prefix
Обратите внимание, что prefix
имеет
значение, только если flags
установлен в EXTR_PREFIX_SAME
,
EXTR_PREFIX_ALL
,
EXTR_PREFIX_INVALID
или EXTR_PREFIX_IF_EXISTS
. Если
в результате добавления префикса, не будет получено
допустимое имя для переменной, она не будет импортирована
в текущую символьную таблицу.
Возвращает количество переменных, успешно импортированных в текущую таблицу символов.
Пример #1 Пример использования extract()
Функцию extract() также можно использовать для импорта в текущую таблицу символов переменных, содержащихся в ассоциативном массиве, возвращённом функцией wddx_deserialize().
<?php
/* Предположим, что $var_array - это массив, полученный в результате
wddx_deserialize */
$size = "large";
$var_array = array("color" => "blue",
"size" => "medium",
"shape" => "sphere");
extract($var_array, EXTR_PREFIX_SAME, "wddx");
echo "$color, $size, $shape, $wddx_size\n";
?>
Результат выполнения данного примера:
blue, large, sphere, medium
Переменная $size не была перезаписана,
потому что мы определили EXTR_PREFIX_SAME
,
в результате чего была создана переменная $wddx_size.
Если был бы определён флаг EXTR_SKIP
,
тогда переменная $wddx_size не была бы создана.
EXTR_OVERWRITE
была бы причиной того,
что переменной $size было бы присвоено
значение "medium", и EXTR_PREFIX_ALL
была бы причиной того, что были бы также созданы новые
переменные $wddx_color,
$wddx_size и $wddx_shape.
Не используйте функцию extract() на
непроверенных данных, таких как пользовательский ввод
($_GET, $_FILES и т.п.).
Если вы сделаете это, например, для того, что бы временно
запустить старый код, использующий
register_globals,
используйте соответствующий флаг flags
для того, что бы не перезаписать уже установленные переменные,
такой как EXTR_SKIP
и удостоверьтесь,
что вы извлекаете содержимое в том же порядке, что указан в
директиве variables_order
в php.ini.
Замечание:
Если у вас все еще включена директива register_globals и вы используете extract() с массивом $_FILES и параметром
EXTR_SKIP
, результат может вас удивить.ВниманиеЭто нерекомендуемая практика и документирована здесь только для полноты картины. Использование register_globals считается устаревшим и вызов extract() на непроверенных данных, таких как $_FILES, как уже было сказано выше, потенциальный риск безопасности. Если вы столкнулись с данным случаем, это означает что вы используете как минимум две плохие практики кодирования.
Вы можете ожидать что-нибудь вроде следующего:<?php
/* Предположим, что $testfile это имя input загрузки файла
и что директива register_globals включена. */
var_dump($testfile);
extract($_FILES, EXTR_SKIP);
var_dump($testfile);
var_dump($testfile['tmp_name']);
?>Однако, вместо этого вы увидите что-нибудь вроде этого:string(14) "/tmp/phpgCCPX8" array(5) { ["name"]=> string(10) "somefile.txt" ["type"]=> string(24) "application/octet-stream" ["tmp_name"]=> string(14) "/tmp/phpgCCPX8" ["error"]=> int(0) ["size"]=> int(4208) } string(14) "/tmp/phpgCCPX8"string(14) "/tmp/phpgCCPX8" string(14) "/tmp/phpgCCPX8" string(1) "/"Это происходит потому, что так как включена директива register_globals, переменная $testfile уже существует в глобальной области видимости в момент вызова extract(). А так как указан параметр
EXTR_SKIP
, $testfile не будет перезаписана содержимым массива$_FILES
, поэтому $testfile останется строкой. Так как к строкам можно обращаться с помощью синтаксиса массивов и нечисловая строка tmp_name интерпретируется как 0, PHP воспринимает $testfile['tmp_name'] как $testfile[0].