compact

Builds an array from existing variables, using each variable's name as the key.

Signature
compact(array|string $var_name, array|string ...$var_names): array
  • Added in PHP 4.0

Parameters

ParameterTypeDescription
$var_namearray|stringA variable name as a string, or an array of variable names (which may itself contain nested arrays of names).
$var_namesoptionalarray|stringAny number of further names or arrays of names, collected variadically.

Return value

arrayAn associative array whose keys are the requested variable names and whose values are those variables' contents. Names that do not resolve to a set variable are omitted.

Errors

Does not throw. Emits an E_WARNING for each name that refers to a variable that is not set (E_NOTICE in PHP 7.3–7.4, silent before that).

Changelog

  • PHP 8.0.0An E_WARNING is now issued if a given string refers to an unset variable.
  • PHP 7.3.0An E_NOTICE is issued if a given string refers to an unset variable; previously such names were silently skipped.

compact takes variable names and returns an array mapping each name to that variable's current value. It is the inverse of extract, and it saves you writing the same identifier twice on every line of an array literal.

When to reach for it

The classic use is handing data to a template or a view renderer: gather $title, $posts and $user into one array with compact('title', 'posts', 'user'). It is also handy for building the payload of a log entry or a JSON response from locals you already have.

What trips people up

Names are passed as strings, not variables — compact($title) looks up a variable whose name is the contents of $title, which is almost never what you meant. It is compact('title').

Since PHP 8.0 a name that does not resolve to a set variable raises an E_WARNING rather than being skipped quietly, so typos now show up in your logs. Guard optional values with isset before compacting them.

Because names are resolved at runtime, static analysers and IDEs cannot see the connection between compact('user') and $user. On code that must survive aggressive refactoring, a plain array literal is easier to maintain even if it is longer.

Superglobals cannot be gathered from inside a function.

Example

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

When to use it

  • Pass a set of local variables to a template renderer in one call.
  • Assemble a structured log context array from values already in scope.
  • Build a JSON response body from named locals without repeating each identifier.

Frequently asked questions

What is the difference between compact and extract?

compact reads variables out of the current scope and returns them as an array, while extract does the reverse and creates variables from an array's keys. They are exact inverses of each other.

Why does compact skip one of my variables?

The named variable is not set in the current scope — often a typo, or a variable defined in an outer scope that a function cannot see. Since PHP 8.0 this also emits an E_WARNING, so check your error log.

Can I use compact inside a closure to grab outer variables?

Only for variables the closure actually imported with use, or that are its own parameters. compact reads the current symbol table, and a closure's scope does not automatically include the enclosing function's variables.

More examples

compact and extract are inverses

compact freezes the two locals into ['title' => 'Release notes', 'year' => 2026]. After unsetting them, extract puts them straight back into scope, so the echo prints Release notes (2026).

Example · php
<?php
$title = 'Release notes';
$year  = 2026;

$data = compact('title', 'year');
unset($title, $year);

extract($data);
echo "$title ($year)\n";

Unset names raise a warning in PHP 8

The handler intercepts the E_WARNING that PHP 8 emits for 'missing', printing it instead of letting it hit the log. The returned array contains only defined => yes; the unresolved name is simply absent rather than being set to null.

Example · php
<?php
$defined = 'yes';

set_error_handler(function ($no, $msg) { echo "warning: $msg\n"; return true; });
$result = compact('defined', 'missing');
restore_error_handler();

print_r($result);

Guarding optional values

isset returns false for a null variable, so 'note' is never added to the name list and no warning is triggered. The dump shows a one-element array containing only id => int(7).

Example · php
<?php
$id = 7;
$note = null;              // set, but null

$names = ['id'];
if (isset($note)) { $names[] = 'note'; }   // null fails isset

var_dump(compact($names));

Discussion

  • Be the first to comment on this lesson.