説明
配列の場合は、配列の全ての要素を数えます。 Countable インターフェイスを実装したオブジェクトの場合は、 Countable::count() の戻り値を返します。
パラメータ
value
-
配列あるいは Countable オブジェクト。
mode
-
オプションの
mode
引数がCOUNT_RECURSIVE
(または 1) にセットされた場合、count() は再帰的に配列をカウントします。 これは多次元配列の全ての要素をカウントするといった場合に特に有効です。警告count() は、再帰を検出して無限ループを回避するようになっています。 しかしその場合 (配列の中に自分自身が複数回登場する場合) は毎回
E_WARNING
を発行し、期待する結果より大きい数を返します。
戻り値
value
の要素の数を返します。
PHP 8.0.0 より前のバージョンでは、
パラメータが配列でもなく
Countable インターフェイスを
実装したオブジェクトでもない場合、1
が返されていました。
ただし、value
が null
の場合、
0
が返されていました。
変更履歴
バージョン | 説明 |
---|---|
8.0.0 |
value パラメータに不正な型を渡した場合に、
TypeError をスローするようになりました。
|
7.2.0 |
value パラメータに不正な型を渡した場合に、
警告を発生させるようになりました。
|
例
例1 count() の例
<?php
$a[0] = 1;
$a[1] = 3;
$a[2] = 5;
var_dump(count($a));
$b[0] = 7;
$b[5] = 9;
$b[10] = 11;
var_dump(count($b));
?>
上の例の出力は以下となります。
int(3) int(3)
例2 Countable|array でない値を渡した場合の count() の例 (悪い例です - 真似しないでね!)
<?php
$b[0] = 7;
$b[5] = 9;
$b[10] = 11;
var_dump(count($b));
var_dump(count(null));
var_dump(count(false));
?>
上の例の出力は以下となります。
int(3) int(0) int(1)
上の例の PHP 7.2 での出力は、このようになります。
int(3) Warning: count(): Parameter must be an array or an object that implements Countable in … on line 12 int(0) Warning: count(): Parameter must be an array or an object that implements Countable in … on line 14 int(1)
上の例の PHP 8 での出力は、このようになります。:
int(3) Fatal error: Uncaught TypeError: count(): Argument #1 ($var) must be of type Countable .. on line 12
例3 再帰的な count() の例
<?php
$food = array('fruits' => array('orange', 'banana', 'apple'),
'veggie' => array('carrot', 'collard', 'pea'));
// recursive count
var_dump(count($food, COUNT_RECURSIVE));
// normal count
var_dump(count($food));
?>
上の例の出力は以下となります。
int(8) int(2)
例4 Countable オブジェクトの例
<?php
class CountOfMethods implements Countable
{
private function someMethod()
{
}
public function count(): int
{
return count(get_class_methods($this));
}
}
$obj = new CountOfMethods();
var_dump(count($obj));
?>
上の例の出力は以下となります。
int(2)
参考
- is_array() - 変数が配列かどうかを検査する
- isset() - 変数が宣言されていること、そして null とは異なることを検査する
- empty() - 変数が空であるかどうかを検査する
- strlen() - 文字列の長さを得る
- is_countable() - 引数が、数えられる値かどうかを調べる
- Arrays
User Contributed Notes 13 notes
[Editor's note: array at from dot pl had pointed out that count() is a cheap operation; however, there's still the function call overhead.]
If you want to run through large arrays don't use count() function in the loops , its a over head in performance, copy the count() value into a variable and use that value in loops for a better performance.
Eg:
// Bad approach
for($i=0;$i<count($some_arr);$i++)
{
// calculations
}
// Good approach
$arr_length = count($some_arr);
for($i=0;$i<$arr_length;$i++)
{
// calculations
}
If you are on PHP 7.2+, you need to be aware of "Changelog" and use something like this:
<?php
$countFruits = is_array($countFruits) || $countFruits instanceof Countable ? count($countFruits) : 0;
?>
You can organize your code to ensure that the variable is an array, or you can extend the Countable so that you don't have to do this check.
For a Non Countable Objects
$count = count($data);
print "Count: $count\n";
Warning: count(): Parameter must be an array or an object that implements Countable in example.php on line 159
#Quick fix is to just cast the non-countable object as an array..
$count = count((array) $data);
print "Count: $count\n";
Count: 250
I actually find the following function more useful when it comes to multidimension arrays when you do not want all levels of the array tree.
// $limit is set to the number of recursions
<?php
function count_recursive ($array, $limit) {
$count = 0;
foreach ($array as $id => $_array) {
if (is_array ($_array) && $limit > 0) {
$count += count_recursive ($_array, $limit - 1);
} else {
$count += 1;
}
}
return $count;
}
?>
A function of one line to find the number of elements that are not arrays, recursively :
function count_elt($array, &$count=0){
foreach($array as $v) if(is_array($v)) count_elt($v,$count); else ++$count;
return $count;
}
My function returns the number of elements in array for multidimensional arrays subject to depth of array. (Almost COUNT_RECURSIVE, but you can point on which depth you want to plunge).
<?php
function getArrCount ($arr, $depth=1) {
if (!is_array($arr) || !$depth) return 0;
$res=count($arr);
foreach ($arr as $in_ar)
$res+=getArrCount($in_ar, $depth-1);
return $res;
}
?>
In example #3, given as:
<?php
$food = array('fruits' => array('orange', 'banana', 'apple'),
'veggie' => array('carrot', 'collard', 'pea'));
// recursive count
var_dump(count($food, COUNT_RECURSIVE));
?>
with the output given as int(8), it may have some readers mistaken, as I was at first: one might take it as keys being counted as well as the inner array entries:
<?php
// NO:
'fruits', 'orange', 'banana', 'apple',
'veggie', 'carrot', 'collard', 'pea'
?>
But actually keys are not counted in count function, and why it is still 8 - because inner arrays are counted as entries as well as their inner elements:
<?php
// YES:
array('orange', 'banana', 'apple'), 'orange', 'banana', 'apple',
array('carrot', 'collard', 'pea'), 'carrot', 'collard', 'pea'
?>
All the previous recursive count solutions with $depth option would not avoid infinite loops in case the array contains itself more than once.
Here's a working solution:
<?php
/**
* Recursively count elements in an array. Behaves exactly the same as native
* count() function with the $depth option. Meaning it will also add +1 to the
* total count, for the parent element, and not only counting its children.
* @param $arr
* @param int $depth
* @param int $i (internal)
* @return int
*/
public static function countRecursive(&$arr, $depth = 0, $i = 0) {
$i++;
/**
* In case the depth is 0, use the native count function
*/
if (empty($depth)) {
return count($arr, COUNT_RECURSIVE);
}
$count = 0;
/**
* This can occur only the first time when the method is called and $arr is not an array
*/
if (!is_array($arr)) {
return count($arr);
}
// if this key is present, it means you already walked this array
if (isset($arr['__been_here'])) {
return 0;
}
$arr['__been_here'] = true;
foreach ($arr as $key => &$value) {
if ($key !== '__been_here') {
if (is_array($value) && $depth > $i) {
$count += self::countRecursive($value, $depth, $i);
}
$count++;
}
}
// you need to unset it when done because you're working with a reference...
unset($arr['__been_here']);
return $count;
}
?>
Empty values are counted:
<?php
$ar[] = 3;
$ar[] = null;
var_dump(count($ar)); //int(2)
?>
You can not get collect sub array count when there is only one sub array in an array:
$a = array ( array ('a','b','c','d'));
$b = array ( array ('a','b','c','d'), array ('e','f','g','h'));
echo count($a); // 4 NOT 1, expect 1
echo count($b); // 2, expected
To get the count of the inner array you can do something like:
$inner_count = count($array[0]);
echo ($inner_count);
In special situations you might only want to count the first level of the array to figure out how many entries you have, when they have N more key-value-pairs.
<?php
$data = [
'a' => [
'bla1' => [
0 => 'asdf',
1 => 'asdf',
2 => 'asdf',
],
'bla2' => [
0 => 'asdf',
1 => 'asdf',
2 => 'asdf',
],
'bla3' => [
0 => 'asdf',
1 => 'asdf',
2 => 'asdf',
],
'bla4' => [
0 => 'asdf',
1 => 'asdf',
2 => 'asdf',
],
],
'b' => [
'bla1' => [
0 => 'asdf',
1 => 'asdf',
2 => 'asdf',
],
'bla2' => [
0 => 'asdf',
1 => 'asdf',
2 => 'asdf',
],
],
'c' => [
'bla1' => [
0 => 'asdf',
1 => 'asdf',
2 => 'asdf',
]
]
];
$count = array_sum(array_values(array_map('count', $data)));
// will return int(7)
var_dump($count);
// will return 31
var_dump(count($data, 1));
?>