extract

Creates variables in the current scope from an array's keys and values.

Signature
extract(array &$array, int $flags = EXTR_OVERWRITE, string $prefix = ""): int
  • Added in PHP 4.0

Parameters

ParameterTypeDescription
$arrayarrayAn associative array whose keys become variable names and whose values become those variables' contents.
$flagsoptionalint= EXTR_OVERWRITEHow to treat collisions and invalid names: EXTR_OVERWRITE, EXTR_SKIP, EXTR_PREFIX_SAME, EXTR_PREFIX_ALL, EXTR_PREFIX_INVALID, EXTR_IF_EXISTS, EXTR_PREFIX_IF_EXISTS, optionally OR-ed with EXTR_REFS.
$prefixoptionalstring= ""Prefix joined to the key with an underscore. Required by the EXTR_PREFIX_* flags and ignored otherwise.

Return value

intThe number of variables successfully imported into the symbol table.

Errors

Does not throw. Keys that are not valid variable names are skipped unless EXTR_PREFIX_INVALID or EXTR_PREFIX_ALL is used.

extract turns an array's keys into live variables in the calling scope: ['id' => 7] becomes $id = 7. It returns how many variables it actually created, which is not always how many keys you gave it.

When to reach for it

Practically the only defensible use is a template renderer — a function that receives a view-data array, calls extract, then includes a PHP template so the template can write $title instead of $data['title']. Every major framework's view layer does exactly this, inside a tightly controlled function.

What trips people up

The security problem is real and old: extract($_GET) lets a request define or overwrite any local variable, including one you use for an authorisation check. Never extract data you did not build yourself, and if you must, use EXTR_SKIP or EXTR_IF_EXISTS so existing variables cannot be clobbered.

The maintenance problem is just as important: variables appear from nowhere, so no reader, IDE or static analyser can tell where $title came from. Keep the extract inside a three-line function and never call it in a long body.

Keys that are not valid PHP identifiers — starting with a digit, containing a dash — are silently skipped unless you pass one of the EXTR_PREFIX_* flags, which is why the return count can be lower than count($array).

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Expose a view-data array as plain variables inside an included PHP template.
  • Unpack a small, internally built config array at the top of a short function.
  • Rehydrate variables previously captured with compact().

Frequently asked questions

Is extract() safe to use?

Only on arrays you built yourself. Calling it on user-controlled input such as $_GET or $_POST lets an attacker create or overwrite arbitrary variables in scope, which is a classic variable-injection vulnerability.

What is the difference between extract and compact?

extract creates variables from an array's keys, while compact builds an array from named variables. They are exact inverses.

Why did extract() import fewer variables than my array has keys?

Keys that are not valid PHP variable names — numeric keys, or keys containing characters like a hyphen — are skipped by default. Pass EXTR_PREFIX_INVALID with a prefix to import them anyway.

More examples

A safe template renderer

Because the extract happens inside a function with a single parameter, there is nothing valuable for a malicious key to overwrite, and EXTR_SKIP protects $data itself. The output shows the ampersand escaped to & and the view count cast to an integer.

Example · php
<?php
function render(array $data): string {
    extract($data, EXTR_SKIP);          // isolated: only $data is in scope
    ob_start();
    echo "<h1>", htmlspecialchars($title), "</h1>\n";
    echo "<p>", (int) $views, " views</p>\n";
    return ob_get_clean();
}

echo render(['title' => 'Ada & Co', 'views' => '1200']);

Invalid keys are skipped or prefixed

'2bad' and 'also-bad' are not valid identifiers, so the plain call imports only one variable. EXTR_PREFIX_INVALID rescues '2bad' by renaming it to v_2bad, but 'also-bad' becomes 'v_also-bad', which still contains a hyphen and is therefore still not a valid variable name — extract() re-checks the prefixed name and skips it, so the second call imports only ok and v_2bad and returns 2, not 3.

Example · php
<?php
$data = ['ok' => 1, '2bad' => 2, 'also-bad' => 3];

echo extract($data), "\n";                           // 1 — two keys skipped
echo extract($data, EXTR_PREFIX_INVALID, 'v'), "\n"; // 2 — 'also-bad' is still skipped

echo $ok, ' ', $v_2bad, "\n";

EXTR_REFS links variable and array

EXTR_REFS makes $count a reference to $data['count'] rather than a copy, so writing to the variable writes through to the array. Without the flag the print_r would still show count => 1.

Example · php
<?php
$data = ['count' => 1];

extract($data, EXTR_REFS);
$count = 99;

print_r($data);   // count is now 99

Discussion

  • Be the first to comment on this lesson.