Signature
count(Countable|array $value, int $mode = COUNT_NORMAL): intPurpose
count() tells you how many elements a container holds. Pass it an array and you get the number of entries in that array. Pass it an object that implements the Countable interface and PHP calls the object's own count() method and returns its result. It is one of the most common array functions, used for loop bounds, validation ("did the user select at least two options?") and reporting.
Signature
Parameters and defaults
$value: an array or aCountableobject. No other type is accepted.$mode: optional. The defaultCOUNT_NORMAL(value0) counts only the top-level entries.COUNT_RECURSIVE(value1) also walks into nested arrays.
Return value and failure cases
The function returns an int: the number of elements. In PHP 8 and later, invalid input is not tolerated quietly:
- A value that is neither an array nor a
Countableobject, such asnull,falseor a string, throws aTypeError. - A
$modeother thanCOUNT_NORMALorCOUNT_RECURSIVEthrows aValueError.
Older PHP versions returned 1 for most non-countable values and 0 for null. Code written against that behaviour must be updated.
Example 1: basic counting
Only the number of entries matters, not the keys. A sparse array with keys 0, 5 and 10 has three elements, and an empty array has zero.
$tags = ['php', 'arrays', 'count'];
$sparse = [0 => 'a', 5 => 'b', 10 => 'c'];
echo count($tags), "\n";
echo count($sparse), "\n";
echo count([]), "\n";3 3 0
Example 2: recursive counting
With COUNT_RECURSIVE, every nested element is counted, and the nested arrays themselves are counted too. Below, the two top-level entries (fruits and veggie) plus three items in each inner array give eight.
$food = [
'fruits' => ['orange', 'banana', 'apple'],
'veggie' => ['carrot', 'collard', 'pea'],
];
echo json_encode([
'normal' => count($food),
'recursive' => count($food, COUNT_RECURSIVE),
]), "\n";{"normal":2,"recursive":8}
Example 3: Countable objects and safe counting
A class that implements Countable decides for itself what its count means. Here a basket reports the total quantity of its items rather than the number of lines. The helper safeCount() uses is_countable() so that unexpected values produce 0 instead of an exception. The last block shows an invalid mode.
final class Basket implements Countable
{
public function __construct(private array $items)
{
}
public function count(): int
{
return array_sum(array_column($this->items, 'qty'));
}
}
function safeCount(mixed $value): int
{
return is_countable($value) ? count($value) : 0;
}
$basket = new Basket([
['sku' => 'A1', 'qty' => 2],
['sku' => 'B2', 'qty' => 3],
]);
echo json_encode([safeCount($basket), safeCount(null), safeCount('abc')]), "\n";
try {
count([1, 2], 5);
} catch (ValueError $e) {
echo "ValueError\n";
}[5,0,0] ValueError
Edge cases
- Gaps in keys do not matter. Only the number of stored entries counts, so
count()is not the same as "highest index plus one". nullvalues still count. An array such as[null, null]has two elements. Useisset()on individual keys when you care about null values.- Recursive mode counts containers too. The result is not just the number of leaf values. Each nested array adds one for itself as well as one for each of its entries.
- Self-referencing arrays.
count()detects recursion to avoid an infinite loop, but it emits anE_WARNINGeach time and returns a higher number than you might expect. - Custom counts can be anything. For a
Countableobject,count()simply returns what the object'scount()method returns, so the number may not equal any visible collection size.
Common mistakes
- Counting a value that may be
null. Database or form code often yieldsnullorfalsewhen nothing was found. In PHP 8 that throws aTypeError. Check withis_array()oris_countable()first, or make sure your functions always return arrays. - Using
count()on strings. It does not measure text length. Usestrlen()for the number of bytes in a string. - Expecting
COUNT_RECURSIVEto count only leaves. If you need only the leaf values, write a small recursive function or flatten the array first. - Recomputing in a loop condition. Writing
for ($i = 0; $i < count($a); $i++)works, but if the array does not change inside the loop you can store the count in a variable first for clarity. - Using
count($x) > 0when$xmay be undefined. An undefined variable isnull, which fails. Initialise arrays before use. - Passing a magic number as the mode. Use the named constants so the intent is clear and only valid modes are used.
Related functions
is_countable()checks whether a value can safely be passed tocount().is_array()checks that a value is an array.isset()tests whether a variable or key exists and is notnull.empty()tests whether a value is considered empty, which is a quick way to check for no elements.strlen()returns the length of a string.
Recap
count() returns the number of elements in an array or Countable object as an int. The default mode counts one level; COUNT_RECURSIVE includes nested arrays and their entries. In PHP 8, non-countable arguments throw a TypeError and invalid modes throw a ValueError, so guard uncertain values with is_countable().
Tested examples
$tags = ['php', 'arrays', 'count'];
$sparse = [0 => 'a', 5 => 'b', 10 => 'c'];
echo count($tags), "\n";
echo count($sparse), "\n";
echo count([]), "\n";
3 3 0
$food = [
'fruits' => ['orange', 'banana', 'apple'],
'veggie' => ['carrot', 'collard', 'pea'],
];
echo json_encode([
'normal' => count($food),
'recursive' => count($food, COUNT_RECURSIVE),
]), "\n";
{"normal":2,"recursive":8}
final class Basket implements Countable
{
public function __construct(private array $items)
{
}
public function count(): int
{
return array_sum(array_column($this->items, 'qty'));
}
}
function safeCount(mixed $value): int
{
return is_countable($value) ? count($value) : 0;
}
$basket = new Basket([
['sku' => 'A1', 'qty' => 2],
['sku' => 'B2', 'qty' => 3],
]);
echo json_encode([safeCount($basket), safeCount(null), safeCount('abc')]), "\n";
try {
count([1, 2], 5);
} catch (ValueError $e) {
echo "ValueError\n";
}
[5,0,0] ValueError