PHP基础教程(88)PHP数组应用函数之统计数组元素个数:搞定这招,老板再也不嫌我数数慢!PHP数组统计终极指南,附送防翻车秘籍

一、 别再用循环当人工计数器了!

那天我同事小王,盯着屏幕念念有词:“一、二、三……” 我探头一看,好家伙,他正用for循环数PHP数组有几个元素!我当场笑喷:“兄弟,你是人类计算器成精吗?”

其实90%的新手都干过这事——不是手动$i++,就是在日记本上画正字。但PHP早就给你备好了超级加速器:count()函数。这玩意儿就像超市结账时的扫码枪,“嘀”一声,管你购物车里丢了多少商品,总价瞬间出来。

二、 count()到底是个什么鬼?

官方说法枯燥得像说明书,咱们来点人话版:
count(array,mode) 就干两件事:

  1. 数你数组里有多少个元素(默认模式)
  2. 加个神秘参数,就能连子孙后代一起数(递归模式)

举个栗子🌰:

$零食柜 = ['薯片', '可乐', '巧克力', '瓜子'];  
echo count($零食柜); // 输出:4  

就这?对,就这么简单!但如果你以为它只会数零食,那就太小看它了。

三、 二维数组?多维迷宫?照数不误!

最近做抽奖系统,遇到个经典场景:

$部门员工 = [  
    '技术部' => ['张三', '李四', '王五'],  
    '市场部' => ['赵六', '钱七'],  
    '人事部' => ['孙八']  
];  

新手噩梦题:公司总共多少人?
菜鸟可能嵌套循环,老鸟直接:

$总人数 = 0;  
foreach($部门员工 as $部门){  
    $总人数 += count($部门);  
}  

但终极解法更骚

$总人数 = count($部门员工, COUNT_RECURSIVE) - count($部门员工);  
// 输出:6  

这里用了COUNT_RECURSIVE模式,它会像扫雷游戏一样,把嵌套数组全部展开数一遍。不过注意:它会把父数组也算作一个元素,所以要减去部门数量。

四、 sizeof():count()的双胞胎兄弟?

很多教程会说“sizeof()是count()的别名”,但!这里有个冷知识:
在远古PHP版本中,sizeof()在某些边缘场景有微妙差异。虽然现在99.9%情况通用,但:

  • count()显得你很专业
  • 团队协作时统一用count避免困惑
  • 面试时能装X:“我通常用count,因为sizeof可能让人误以为是取内存大小”

五、 空数组、null、未定义变量的修罗场

这才是翻车高发区!看这段夺命代码:

$未初始化数组;  
echo count($未初始化数组); // 警告+返回0?不!是警告+返回1!  

防翻车守则

  1. 先用isset()检查变量是否存在
  2. is_array()确认它真是数组
  3. 安全写法模板:
$人数 = is_array($员工列表) ? count($员工列表) : 0;  

六、 实战篇:统计函数玩出花的7个场景

场景1:烧烤店库存预警系统
$库存 = [  
    '羊肉串' => 150,  
    '鸡翅' => 30,  // 低于警戒线!  
    '馒头片' => 200  
];  

$低库存商品 = [];  
foreach($库存 as $商品 => $数量){  
    if($数量 < 50){  
        $低库存商品[] = $商品;  
    }  
}  

echo "急需补货的有:" . implode('、', $低库存商品);  
echo "共" . count($低库存商品) . "种商品";  
场景2:投票系统去重统计
$投票记录 = ['张三', '李四', '张三', '王五', '李四'];  
$有效票数 = count(array_unique($投票记录)); // 先去重再统计!  
echo "有效票数:$有效票数"; // 输出:3  
场景3:动态生成分页按钮
$所有文章 = [...]; // 假设100篇文章  
$每页显示 = 10;  
$总页数 = ceil(count($所有文章) / $每页显示); // ceil()向上取整  

// 生成分页按钮  
for($i = 1; $i <= $总页数; $i++){  
    echo "<button>第{$i}页</button> ";  
}  

七、 性能暗战:count()的隐藏属性

有个江湖传说:“count()很耗性能”。实测打脸:

  • count()是O(1)时间复杂度,因为PHP数组内部维护了长度计数器
  • 但!在循环里每次都count()就是作死:
// 糟糕写法  
for($i = 0; $i < count($巨大数组); $i++){  
    // 每次循环都数一遍,CPU在哭泣  
}  

// 优雅写法  
$总数 = count($巨大数组);  
for($i = 0; $i < $总数; $i++){  
    // 只数一次,CPU爱你  
}  

八、 扩展包:那些冷门但好用的统计函数

1. array_count_values() —— 统计值出现的次数
$考试成绩 = [85, 90, 85, 78, 90, 90];  
$分数分布 = array_count_values($考试成绩);  
print_r($分数分布);  
/* 输出:  
[  
    85 => 2,  
    90 => 3,  
    78 => 1  
]  
*/  
2. 统计二维数组某列的和
$订单明细 = [  
    ['商品' => '手机', '数量' => 2],  
    ['商品' => '耳机', '数量' => 5],  
    ['商品' => '贴膜', '数量' => 10]  
];  

$总数量 = array_sum(array_column($订单明细, '数量'));  
echo "总销量:$总数量"; // 输出:17  

九、 完整实战:班级成绩分析系统

下面这个例子,囊括了今天所有知识点:

<?php
/**
 * 班级成绩分析系统 - 统计函数实战
 */

class 成绩分析器 {
    private $学生数据;
    
    public function __construct($数据) {
        $this->学生数据 = $数据;
    }
    
    // 1. 基础统计
    public function 获取总人数() {
        return count($this->学生数据);
    }
    
    // 2. 统计各分数段人数
    public function 分数段分析() {
        $分段 = ['优秀' => 0, '良好' => 0, '及格' => 0, '不及格' => 0];
        
        foreach($this->学生数据 as $学生) {
            $分数 = $学生['分数'];
            
            if($分数 >= 90) $分段['优秀']++;
            elseif($分数 >= 80) $分段['良好']++;
            elseif($分数 >= 60) $分段['及格']++;
            else $分段['不及格']++;
        }
        
        return $分段;
    }
    
    // 3. 统计缺考人数
    public function 统计缺考() {
        $缺考名单 = [];
        
        foreach($this->学生数据 as $学号 => $学生) {
            if($学生['缺考']) {
                $缺考名单[] = $学生['姓名'];
            }
        }
        
        return [
            '人数' => count($缺考名单),
            '名单' => $缺考名单
        ];
    }
    
    // 4. 生成统计报告
    public function 生成报告() {
        $报告 = "==== 成绩分析报告 ====\n";
        $报告 .= "总人数:" . $this->获取总人数() . "\n";
        
        $分段 = $this->分数段分析();
        $报告 .= "\n【分数段分布】\n";
        foreach($分段 as $段名 => $人数) {
            $百分比 = round($人数 / $this->获取总人数() * 100, 2);
            $报告 .= "{$段名}:{$人数}人 ({$百分比}%)\n";
        }
        
        $缺考 = $this->统计缺考();
        $报告 .= "\n【缺考统计】\n";
        $报告 .= "缺考人数:" . $缺考['人数'] . "\n";
        
        if($缺考['人数'] > 0) {
            $报告 .= "缺考名单:" . implode('、', $缺考['名单']) . "\n";
        }
        
        return $报告;
    }
}

// ====== 实战数据 ======
$班级数据 = [
    '001' => ['姓名' => '张三', '分数' => 95, '缺考' => false],
    '002' => ['姓名' => '李四', '分数' => 78, '缺考' => false],
    '003' => ['姓名' => '王五', '分数' => 88, '缺考' => false],
    '004' => ['姓名' => '赵六', '分数' => 55, '缺考' => false],
    '005' => ['姓名' => '钱七', '分数' => 92, '缺考' => false],
    '006' => ['姓名' => '孙八', '分数' => 0, '缺考' => true], // 缺考
    '007' => ['姓名' => '周九', '分数' => 61, '缺考' => false],
    '008' => ['姓名' => '吴十', '分数' => 84, '缺考' => false],
    '009' => ['姓名' => '郑十一', '分数' => 0, '缺考' => true], // 缺考
];

// 运行分析
$分析器 = new 成绩分析器($班级数据);
echo $分析器->生成报告();

// ====== 额外技巧:快速统计 ======
echo "\n【快速统计技巧演示】\n";

// 技巧1:使用array_column提取分数列
$所有分数 = array_column($班级数据, '分数');
echo "平均分:" . array_sum($所有分数) / count($所有分数) . "\n";

// 技巧2:筛选及格人数(使用array_filter)
$及格人数 = count(array_filter($所有分数, function($分数) {
    return $分数 >= 60;
}));
echo "及格人数:{$及格人数}\n";

// 技巧3:最高分/最低分(排除0分缺考)
$有效分数 = array_filter($所有分数, function($分数) {
    return $分数 > 0;
});
echo "最高分:" . max($有效分数) . ",最低分:" . min($有效分数) . "\n";
?>

十、 常见坑爹问题排查指南

Q1:为什么count()返回1,我的数组明明是空的?
A:大概率你数的是null或者没初始化。先var_dump()看看变量真身。

Q2:递归模式把我搞晕了,有简单理解方式吗?
A:想象成拆快递——普通模式只数外箱,递归模式会把箱子里的每个小包装都数一遍。

Q3:超大数组统计会不会内存爆炸?
A:count()只读取数组头信息,不遍历内容,所以就算数组有100万元素,它也是瞬间完成。

十一、 升级思维:统计是为了什么?

最后升华一下:数数组不是目的,通过数据驱动决策才是。比如:

  • 统计商品销量 → 决定下个月进货量
  • 统计用户停留时长 → 优化页面设计
  • 统计API调用频率 → 优化服务器配置

记住这个心法:统计是眼睛,决策是大脑,代码是手脚。三者配合,你写的就不再是代码,而是商业解决方案。


彩蛋:测试题——下面代码输出什么?

$谜之数组 = [1, 2, [3, 4, [5]], 6];  
echo count($谜之数组, COUNT_RECURSIVE);  

想不出来?亲自跑一遍吧!编程最爽的时刻,不就是“啊哈,原来如此”的顿悟瞬间吗?

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

值引力

持续创作,多谢支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值