处理数组时经常需要取其中一部分,比如分页、取前几条数据、跳过开头几条。array_slice()就是专门干这个的——不修改原数组,直接从原数组里切出一段返回。
好比切蛋糕,原蛋糕不动,切一块下来给你。
语法格式
array array_slice(array $array, int $offset [, int $length = NULL [, bool $preserve_keys = FALSE ]]): array
参数说明:
| 参数 | 说明 | 必填? |
|---|---|---|
| array | 要切片的原数组 | 必填 |
| offset | 开始位置,正整数从前往后数,负整数从后往前数 | 必填 |
| length | 切多长,不传则取到末尾 | 可选 |
| preserve_keys | 是否保留原键名,默认false(重置为0,1,2) | 可选 |
返回值: 切出来的那一段数组。
offset的规律
-
offset = 0:从第一个元素开始 -
offset = 2:从第三个元素开始(0是第一个,所以2是第三个) -
offset = -1:从倒数第一个元素开始 -
offset = -3:从倒数第三个元素开始
length的规律
-
length = 2:取2个元素 -
length = -1:取到倒数第一个之前(不包括倒数第一个) -
length = -2:取到倒数第二个之前 -
不传length:从offset一直取到末尾
示例1:基础切片
<?php
$students = ["张伟", "李芳", "王磊", "赵敏", "刘强", "陈晨"];
// 从第2个开始取3个(下标1开始,取3个)
$slice1 = array_slice($students, 1, 3);
print_r($slice1);
?>
输出:
Array
(
[0] => 李芳
[1] => 王磊
[2] => 赵敏
)
键名被重置成了0、1、2。原数组没变化。
示例2:用负数offset从尾部开始取
<?php
$products = ["键盘", "鼠标", "显示器", "耳机", "摄像头", "音箱"];
// 从倒数第3个开始取2个
$slice = array_slice($products, -3, 2);
print_r($slice);
?>
输出:
Array
(
[0] => 耳机
[1] => 摄像头
)
负数offset从尾部数:-1是"音箱",-2是"摄像头",-3是"耳机",所以从"耳机"开始。
示例3:负数的length
<?php
$scores = [85, 92, 78, 88, 96, 74, 89];
// 从第2个开始,取到倒数第2个之前(不包括倒数第2个)
$slice = array_slice($scores, 1, -2);
print_r($slice);
?>
输出:
Array
(
[0] => 92
[1] => 78
[2] => 88
[3] => 96
)
原数组下标0=85,下标1=92,倒数第二个是74(下标5),取到它之前,所以拿到下标1到4。
示例4:preserve_keys保留原键名
<?php
$user_info = [
"id" => 1001,
"name" => "代码号001",
"email" => "user001@test.com",
"phone" => "13800001111",
"address" => "北京市朝阳区"
];
// 保留原键名
$slice = array_slice($user_info, 1, 2, true);
print_r($slice);
?>
输出:
Array
(
[name] => 代码号001
[email] => user001@test.com
)
注意:没加true的话,键名会变成0和1,会丢失"name"和"email"这些有意义的键名。处理关联数组时,记得把第四个参数设为true。
个人经验分享
-
分页功能的实现
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1; $per_page = 10; $offset = ($page - 1) * $per_page; $page_data = array_slice($all_data, $offset, $per_page);数据量小的时候(几千条以下)可以用这个方法做分页。数据量大就别用了,会在内存里撑爆。
-
和array_splice的区别
-
array_slice():只取一部分,原数组不变 -
array_splice():取一部分后,原数组会被删除那部分
绝大多数场景用array_slice()就够了。我一般只在需要原地修改原数组时才用splice。
-
-
取前N条数据
$top_5 = array_slice($data, 0, 5); -
取后N条数据
$last_5 = array_slice($data, -5); -
跳过前N条,取剩下的全部
$rest = array_slice($data, 3);
示例5:代码号学习编程场景
<?php
// 模拟从数据库查出来的100条成绩记录
$all_scores = range(60, 100); // 简化演示,实际是查出来的数组
shuffle($all_scores); // 打乱顺序
// 需求:分页展示,每页15条,展示第3页
$page = 3;
$per_page = 15;
$offset = ($page - 1) * $per_page;
$page_scores = array_slice($all_scores, $offset, $per_page);
echo "第{$page}页,共" . count($page_scores) . "条数据:\n";
print_r($page_scores);
?>
示例6:边界情况处理
<?php
$empty = [];
$data = ["a", "b", "c"];
// offset超过数组长度
$result1 = array_slice($empty, 5);
var_dump($result1); // []
// offset等于数组长度
$result2 = array_slice($data, 3);
var_dump($result2); // []
// length为0
$result3 = array_slice($data, 1, 0);
var_dump($result3); // []
?>
offset大于等于数组长度时返回空数组,不会报错。
示例7:关联数组保留键名对比
<?php
$course = [
"c01" => "PHP基础",
"c02" => "MySQL教程",
"c03" => "JavaScript",
"c04" => "Laravel框架"
];
// 不保留键名
$slice1 = array_slice($course, 1, 2);
// 保留键名
$slice2 = array_slice($course, 1, 2, true);
echo "不保留键名:\n";
print_r($slice1);
echo "\n保留键名:\n";
print_r($slice2);
?>
输出:
不保留键名:
Array
(
[0] => MySQL教程
[1] => JavaScript
)
保留键名:
Array
(
[c02] => MySQL教程
[c03] => JavaScript
)
本节课程知识要点
-
array_slice()从数组中截取一段,不修改原数组 -
offset支持负数(从尾部开始数)
-
length支持负数(取到倒数第N个之前)
-
处理关联数组时记得把
preserve_keys设为true -
offset超过数组长度时返回空数组
-
分页、取前N条、跳过前N条是常见使用场景
-
从PHP 4.0开始可用