Signature
extract(array &$array, int $flags = EXTR_OVERWRITE, string $prefix = ""): intPurpose
extract() copies the entries of an associative array into the current symbol table. Each key becomes a variable name and each value becomes that variable's value. It is handy when a function receives a small, well-known array of fields and you want to use them as plain variables. It is also easy to misuse, because it creates variables that are invisible to a reader scanning the code.
Signature
Parameters and defaults
$array: the source array. Keys are treated as variable names. The parameter is a reference because theEXTR_REFSflag can bind the new variables to the array's elements.$flags: controls how collisions and invalid names are handled. The default isEXTR_OVERWRITE.$prefix: text placed in front of a name, joined to it with an underscore. It is only needed for the prefix-related flags.
The flags are:
EXTR_OVERWRITE: replace an existing variable on collision.EXTR_SKIP: keep the existing variable on collision.EXTR_PREFIX_SAME: on collision, create a prefixed variable instead.EXTR_PREFIX_ALL: prefix every name.EXTR_PREFIX_INVALID: prefix only invalid or numeric names.EXTR_IF_EXISTS: overwrite only variables that already exist.EXTR_PREFIX_IF_EXISTS: create prefixed variables only when the unprefixed one already exists.EXTR_REFS: import references rather than copies. You can combine it with another flag using|.
Return value and failures
The function returns an int: the number of variables successfully imported. Keys that are not valid variable names are skipped and not counted. Under EXTR_SKIP, a skipped collision is not counted either. An invalid flag value, a missing prefix when the chosen flag requires one, or a prefix that is not a valid identifier raises a ValueError.
Example 1: basic extraction inside a function
The array has one key that cannot be a variable name, so only two variables are created.
function describe(array $row): string {
$count = extract($row);
return "$count: $name is $age";
}
echo describe(['name' => 'Ada', 'age' => 36, 'bad key' => 1]), "\n";2: Ada is 36
Calling extract() inside a function keeps the new variables local to that function, which limits the damage if names collide.
Example 2: handling collisions with a prefix
Here $size already exists. With EXTR_PREFIX_SAME, the colliding key is stored as $item_size while $size keeps its value.
$size = "large";
$data = ["color" => "blue", "size" => "medium"];
$count = extract($data, EXTR_PREFIX_SAME, "item");
echo json_encode([$count, $color, $size, $item_size], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";[2,"blue","large","medium"]
Both entries were imported, so the count is 2.
Example 3: numeric keys and references
A numeric key is not a valid variable name by itself. EXTR_PREFIX_ALL fixes that by giving every name a prefix. Adding EXTR_REFS makes the new variables references into the original array.
$settings = ["debug" => false, 5 => "five"];
$count = extract($settings, EXTR_PREFIX_ALL | EXTR_REFS, "cfg");
$cfg_debug = true;
echo json_encode([$count, $settings["debug"], $cfg_5]), "\n";[2,true,"five"]
Assigning to $cfg_debug changed $settings["debug"] because the two are bound together. The array must be a real variable for this to work, not a temporary value.
Edge cases
- A plain list such as
['a', 'b']imports nothing with the default flag, because numeric keys are invalid names. UseEXTR_PREFIX_ALLorEXTR_PREFIX_INVALIDwith a prefix to import them. - If the prefixed result is still not a valid variable name, that entry is not imported.
EXTR_IF_EXISTSis useful for whitelisting: declare the variables you accept, then only those are updated.- An empty array imports nothing and returns
0.
Common mistakes
- Extracting untrusted input. Running
extract()on request data lets a user choose variable names and overwrite your own. If you must, useEXTR_SKIPor a whitelist approach withEXTR_IF_EXISTS, but reading the array keys directly is safer. - Relying on invisible variables. Readers and static analysis tools cannot see where
$namecame from. Prefer$row['name']for anything beyond a tiny scope. - Forgetting the prefix. Flags such as
EXTR_PREFIX_ALLneed a prefix argument. Omitting it is an error. - Ignoring the return value. The count tells you how many keys were usable. A lower number than
count($array)signals skipped keys. - Expecting lists to work. Numerically indexed arrays are not imported with the default flags.
- Mixing up copy and reference. Without
EXTR_REFS, changing the variable does not alter the array.
Related functions
compact()does the reverse: it builds an array from named variables.list()and array destructuring assign array values to variables explicitly, which is usually clearer thanextract().
Recap
extract() imports array entries as variables and returns how many it created. Flags decide what happens on collisions, with invalid names and with references. Use it sparingly, inside small scopes, with trusted arrays, and prefer explicit destructuring when you can.
Tested examples
function describe(array $row): string {
$count = extract($row);
return "$count: $name is $age";
}
echo describe(['name' => 'Ada', 'age' => 36, 'bad key' => 1]), "\n";
2: Ada is 36
$size = "large";
$data = ["color" => "blue", "size" => "medium"];
$count = extract($data, EXTR_PREFIX_SAME, "item");
echo json_encode([$count, $color, $size, $item_size], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
[2,"blue","large","medium"]
$settings = ["debug" => false, 5 => "five"];
$count = extract($settings, EXTR_PREFIX_ALL | EXTR_REFS, "cfg");
$cfg_debug = true;
echo json_encode([$count, $settings["debug"], $cfg_5]), "\n";
[2,true,"five"]