Signature
is_array(mixed $value): boolPurpose
is_array() answers one question: is the value you hold a PHP array right now? It is a type check, so it never converts anything and never looks inside the value. It is most useful at boundaries, where data arrives from somewhere you do not control: decoded JSON, function arguments declared as mixed, configuration trees or the results of other functions.
Signature
Parameters and defaults
$value is the only parameter. It is required and has no default. It accepts any type, which is the point of the function: you can pass a string, an integer, null, an object or an array without causing a type error.
Return value and failure cases
The function returns true when the value is an array and false for everything else. It does not throw exceptions for unexpected types, so there is no failure mode to catch. If you pass a variable that does not exist, PHP reports the undefined variable as usual and the function then sees null, so the result is false. Avoid relying on that. Initialise your variables, or use isset() or the null coalescing operator when a value may be missing.
Example 1: what counts as an array
Only real arrays return true, including empty ones. Objects, null, strings and numbers return false.
$values = [[1, 2], 'text', 42, null, new stdClass(), []];
$results = [];
foreach ($values as $value) {
$results[] = is_array($value);
}
echo json_encode($results);[true,false,false,false,false,true]
The first and last entries are arrays, so they give true. The other four give false.
Example 2: accepting several input shapes
A common use is a function that takes either a list or a single value and always returns an array. Check for an array first, then handle the scalar case.
function normalizeTags(mixed $tags): array
{
if (is_array($tags)) {
return array_values($tags);
}
if (is_string($tags) && $tags !== '') {
return [$tags];
}
return [];
}
echo json_encode([
normalizeTags(['php', 'types']),
normalizeTags('php'),
normalizeTags(null),
normalizeTags(['a' => 'x', 'b' => 'y']),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);[["php","types"],["php"],[],["x","y"]]
Note that array_values() drops the string keys of the last input, so the result is always a plain list.
Example 3: walking nested data and knowing the limits
When you process a tree of settings, is_array() separates branches from leaves. The same example shows two limits: an ArrayObject is an object, so it is not an array, and an array being an array says nothing about whether it is a list.
$config = ['db' => ['host' => 'localhost'], 'debug' => false, 'paths' => ['a', 'b']];
$report = [];
foreach ($config as $key => $value) {
$report[$key] = is_array($value) ? count($value) : 'scalar';
}
$report['arrayObject'] = is_array(new ArrayObject([1, 2]));
$report['list'] = is_array([3 => 'x']) && array_is_list([3 => 'x']);
echo json_encode($report, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);{"db":1,"debug":"scalar","paths":2,"arrayObject":false,"list":false}The db branch has one entry and paths has two. debug is a leaf. The array [3 => 'x'] is an array but not a list, because its first key is not 0.
Edge cases
- An empty array returns
true. Use$value === []orcount()when you also need to know whether it has elements. - Objects that behave like arrays, such as
ArrayObjector classes implementingArrayAccess, returnfalse. - A callable written as
['ClassName', 'method']is an ordinary array, sois_array()returnstruefor it. Useis_callable()if you need to know whether it can be called. - Resources, closures, booleans, floats and strings all return
false. - The function checks only the top level. A nested array does not change the answer for the outer one, and an array of strings is still just an array.
Common mistakes
- Treating a truthy value as an array. Code such as
if ($data)is true for non-empty strings and objects too. Useis_array($data)when the type matters. - Expecting
is_array()to validate shape. It does not check keys, value types or list order. Combine it witharray_is_list(),array_key_exists()or your own checks. - Using it for anything you can loop over. Objects implementing
Traversablework inforeachbut failis_array(). If you need to accept both, test foriterablein a type declaration or checkis_iterable(). - Checking an array that came from
json_decode()without the associative flag. By default JSON objects decode tostdClass, which is not an array. Passtrueas the second argument if you want arrays. - Calling it on a value that might not be defined. Prevent the warning by initialising the variable instead of relying on the
nullresult.
Related functions
array_is_list()checks whether an array has sequential keys starting at zero.is_string(),is_int()andis_float()check other scalar types.is_object()checks for objects, whichis_array()never accepts.
Recap
is_array(mixed $value): bool returns true only for real PHP arrays, empty or not, and false for everything else, with no exceptions. It tests the type of the outer value only, so pair it with other checks when you also care about keys, contents or array-like objects.
Tested examples
$values = [[1, 2], 'text', 42, null, new stdClass(), []];
$results = [];
foreach ($values as $value) {
$results[] = is_array($value);
}
echo json_encode($results);[true,false,false,false,false,true]
function normalizeTags(mixed $tags): array
{
if (is_array($tags)) {
return array_values($tags);
}
if (is_string($tags) && $tags !== '') {
return [$tags];
}
return [];
}
echo json_encode([
normalizeTags(['php', 'types']),
normalizeTags('php'),
normalizeTags(null),
normalizeTags(['a' => 'x', 'b' => 'y']),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);[["php","types"],["php"],[],["x","y"]]
$config = ['db' => ['host' => 'localhost'], 'debug' => false, 'paths' => ['a', 'b']];
$report = [];
foreach ($config as $key => $value) {
$report[$key] = is_array($value) ? count($value) : 'scalar';
}
$report['arrayObject'] = is_array(new ArrayObject([1, 2]));
$report['list'] = is_array([3 => 'x']) && array_is_list([3 => 'x']);
echo json_encode($report, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);{"db":1,"debug":"scalar","paths":2,"arrayObject":false,"list":false}