PHP 8.1: Warning on compact
function calls with non-string and non-array string parameters
compact
function creates an array containing variable names and their values, from a list of variable names passed to the function.
$fruit = 'Apple';
$color = 'Red';
$origin = 'New Zealand';
compact('fruit', 'color', 'origin');
// ['fruit' => "Apple", 'color' => "Red", 'origin' => "New Zealand"]
Historically, the compact
function has been forgiving; On string values that cannot be resolved to a variable syntax, this function skips that value without further warnings.
In PHP 7.3, the compact
function was changed to emit a notice on undefined variables, and later updated to emit a warning instead in PHP 8.0.
compact
function's documentation shows that it will only accept string
parameters, or only array
values with string
values.
function compact(array|string $var_name, array|string ...$var_names): array {}
Despite the function documentation, the compact
function accepted non-string and non-array parameters, but silently ignored them.
For example, the following snippets does not emit any warnings prior to PHP 8.1.
compact(null);
// []
compact(new stdClass());
// []
compact(42);
// []
$a = 1; $b = 2;
compact('a', 42, 'b');
// ['a' => 1, 'b' => 2]
Declaring strict-types with declare(strict_types=1)
does not make compact
function perform a strict type checking.
This behavior is changed in PHP 8.1; In PHP 8.1, compact
function emits a warning on non-string or an array that does not contain all-string keys.
compact(null);
// []
PHP Warning: compact(): Argument #1 must be string or array of strings, null given in ... on line ...
Note that declaring strict-types (
declare(strict_types=1)
) still has no impact, and does not causecompact
function to throw type errors.
The warning is emitted for numbers (that cannot be used to start a variable name), objects, null
, bool
values, or on arrays if it contains a value that is not of an allowed type.
$a = 16;
compact('a', [null, false, 'a', 42], new stdClass);
PHP Warning: compact(): Argument #2 must be string or array of strings, null given in ... on line ...
PHP Warning: compact(): Argument #2 must be string or array of strings, bool given in ... code on line ...
PHP Warning: compact(): Argument #2 must be string or array of strings, int given in ... on line ...
PHP Warning: compact(): Argument #3 must be string or array of strings, stdClass given in ... on line ...
The warning is emitted for each occurrence of illegal types.
Related Changes
- PHP 8.0: Internal function warnings now throw
TypeError
andValueError
exceptions - PHP 8.0: Default error reporting is set to
E_ALL
- PHP 8.0:
@
Error Suppression operator does not silent fatal errors - PHP 7.3: Warning on undefined variable names passed to
compact
Backwards Compatibility Impact
compact
function allowed non-string and non-string-array values prior to PHP 8.1, despite the documentation. The new warning emitted on PHP 8.1 can be avoided by simply not passing those values to the compact
function, either by removing the known illegal values, or by filtering the values prior to passing them to the compact
function.
The @
error suppressor operator can suppress the warning (@compact(null)
), but it is often not a good idea because it does not prevent the root cause.
In PHP 9.0, this warning will be upgraded to throw a TypeError
exception.