本文目录导读:

我来封装一个功能全面的PHP数组工具类,包含常用且实用的数组操作方法。
完整版数组工具类
<?php
/**
* 数组工具类
*
* 提供常用数组操作的静态方法封装
*/
class ArrayUtil
{
/**
* 获取数组指定key的值,支持默认值和点语法
*
* @param array $array 数组
* @param string $key 键名,支持点语法如 'a.b.c'
* @param mixed $default 默认值
* @return mixed
*/
public static function get(array $array, $key, $default = null)
{
if (is_null($key)) {
return $array;
}
if (isset($array[$key])) {
return $array[$key];
}
// 点语法支持
if (strpos($key, '.') !== false) {
$keys = explode('.', $key);
foreach ($keys as $segment) {
if (!is_array($array) || !isset($array[$segment])) {
return $default;
}
$array = $array[$segment];
}
return $array;
}
return $default;
}
/**
* 设置数组指定key的值,支持点语法
*
* @param array $array 数组(引用传递)
* @param string $key 键名
* @param mixed $value 值
* @return void
*/
public static function set(array &$array, $key, $value)
{
if (is_null($key)) {
$array = $value;
return;
}
$keys = explode('.', $key);
while (count($keys) > 1) {
$key = array_shift($keys);
if (!isset($array[$key]) || !is_array($array[$key])) {
$array[$key] = [];
}
$array = &$array[$key];
}
$array[array_shift($keys)] = $value;
}
/**
* 检查数组中是否存在某个key
*
* @param array $array 数组
* @param string $key 键名
* @return bool
*/
public static function has(array $array, $key)
{
if (isset($array[$key])) {
return true;
}
if (strpos($key, '.') !== false) {
$keys = explode('.', $key);
foreach ($keys as $segment) {
if (!is_array($array) || !isset($array[$segment])) {
return false;
}
$array = $array[$segment];
}
return true;
}
return false;
}
/**
* 删除数组中的某个key
*
* @param array $array 数组(引用传递)
* @param string $key 键名
* @return void
*/
public static function remove(array &$array, $key)
{
if (isset($array[$key])) {
unset($array[$key]);
return;
}
if (strpos($key, '.') !== false) {
$keys = explode('.', $key);
$last = array_pop($keys);
$target = &$array;
foreach ($keys as $segment) {
if (!isset($target[$segment]) || !is_array($target[$segment])) {
return;
}
$target = &$target[$segment];
}
unset($target[$last]);
}
}
/**
* 数组去重(支持多维数组)
*
* @param array $array 数组
* @return array
*/
public static function unique(array $array)
{
$result = [];
foreach ($array as $key => $value) {
if (is_array($value)) {
$value = self::unique($value);
}
$result[$key] = $value;
}
// 使用序列化进行去重
$serialized = array_map('serialize', $result);
$unique = array_unique($serialized);
return array_intersect_key($result, $unique);
}
/**
* 扁平化多维数组
*
* @param array $array 多维数组
* @param string $prefix 前缀
* @return array
*/
public static function flatten(array $array, $prefix = '')
{
$result = [];
foreach ($array as $key => $value) {
if (is_array($value) && !empty($value)) {
$result = array_merge($result, self::flatten($value, $prefix . $key . '.'));
} else {
$result[$prefix . $key] = $value;
}
}
return $result;
}
/**
* 将扁平数组转换为多维数组
*
* @param array $array 扁平数组
* @return array
*/
public static function unflatten(array $array)
{
$result = [];
foreach ($array as $key => $value) {
self::set($result, $key, $value);
}
return $result;
}
/**
* 数组排序(支持按多个字段排序)
*
* @param array $array 数组
* @param string|array $field 排序字段或规则数组
* @param string $order 排序方式 ASC/DESC
* @param int $sortType 排序类型
* @return array
*/
public static function orderBy(array $array, $field, $order = 'ASC', $sortType = SORT_REGULAR)
{
if (empty($array)) {
return $array;
}
// 支持多字段排序
if (is_array($field)) {
$args = [];
foreach ($field as $f => $o) {
$args[] = array_column($array, $f);
$args[] = ($o === 'DESC') ? SORT_DESC : SORT_ASC;
$args[] = $sortType;
}
$args[] = &$array;
call_user_func_array('array_multisort', $args);
return $array;
}
$column = array_column($array, $field);
array_multisort($column, ($order === 'DESC' ? SORT_DESC : SORT_ASC), $sortType, $array);
return $array;
}
/**
* 分组数组
*
* @param array $array 数组
* @param string|callable $key 分组键或回调函数
* @return array
*/
public static function groupBy(array $array, $key)
{
$result = [];
foreach ($array as $item) {
if (is_callable($key)) {
$groupKey = $key($item);
} else {
$groupKey = $item[$key] ?? '';
}
$result[$groupKey][] = $item;
}
return $result;
}
/**
* 提取指定字段构成新数组
*
* @param array $array 原数组
* @param string|array $columns 字段名或多个字段
* @param bool $reindex 是否重新索引
* @return array
*/
public static function pluck(array $array, $columns, $reindex = true)
{
$result = [];
if (is_string($columns)) {
$columns = [$columns];
}
foreach ($array as $item) {
if (count($columns) === 1) {
$result[] = $item[$columns[0]] ?? null;
} else {
$row = [];
foreach ($columns as $col) {
$row[$col] = $item[$col] ?? null;
}
$result[] = $row;
}
}
if (!$reindex) {
$result = array_combine(array_keys($array), array_values($result));
}
return $result;
}
/**
* 根据条件筛选数组
*
* @param array $array 数组
* @param array $conditions 条件数组 ['field' => value] 或 ['field' => ['gt' => 5]]
* @return array
*/
public static function where(array $array, array $conditions)
{
return array_values(array_filter($array, function ($item) use ($conditions) {
foreach ($conditions as $key => $value) {
if (is_array($value)) {
$operator = array_key_first($value);
$compareValue = $value[$operator];
switch ($operator) {
case 'gt':
if (!($item[$key] ?? null) > $compareValue) return false;
break;
case 'lt':
if (!($item[$key] ?? null) < $compareValue) return false;
break;
case 'gte':
if (!($item[$key] ?? null) >= $compareValue) return false;
break;
case 'lte':
if (!($item[$key] ?? null) <= $compareValue) return false;
break;
case 'eq':
if (($item[$key] ?? null) != $compareValue) return false;
break;
case 'neq':
if (($item[$key] ?? null) == $compareValue) return false;
break;
case 'in':
if (!in_array($item[$key] ?? null, $compareValue)) return false;
break;
case 'not_in':
if (in_array($item[$key] ?? null, $compareValue)) return false;
break;
case 'contains':
if (strpos($item[$key] ?? '', $compareValue) === false) return false;
break;
default:
if (($item[$key] ?? null) != $value) return false;
}
} else {
if (($item[$key] ?? null) != $value) return false;
}
}
return true;
}));
}
/**
* 分页数组
*
* @param array $array 数组
* @param int $page 页码
* @param int $size 每页数量
* @return array ['data' => [], 'total' => int, 'page' => int, 'size' => int]
*/
public static function paginate(array $array, $page = 1, $size = 10)
{
$total = count($array);
$totalPages = ceil($total / $size);
$page = max(1, min($page, $totalPages));
$offset = ($page - 1) * $size;
$data = array_slice($array, $offset, $size);
return [
'data' => $data,
'total' => $total,
'page' => $page,
'size' => $size,
'total_pages' => $totalPages
];
}
/**
* 多维数组转单列
*
* @param array $array 数组
* @return array
*/
public static function toFlat($array)
{
$result = [];
array_walk_recursive($array, function ($value, $key) use (&$result) {
$result[] = $value;
});
return $result;
}
/**
* 二维数组根据某个字段去重
*
* @param array $array 二维数组
* @param string $field 去重字段
* @return array
*/
public static function distinct(array $array, $field)
{
$result = [];
$seen = [];
foreach ($array as $item) {
$value = $item[$field] ?? '';
if (!isset($seen[$value])) {
$seen[$value] = true;
$result[] = $item;
}
}
return $result;
}
/**
* 数组转XML
*
* @param array $array 数组
* @param string $root 根节点名称
* @param string $encoding 编码
* @return string
*/
public static function toXml(array $array, $root = 'root', $encoding = 'UTF-8')
{
$xml = '<?xml version="1.0" encoding="' . $encoding . '"?>';
$xml .= '<' . $root . '>';
$xml .= self::arrayToXml($array);
$xml .= '</' . $root . '>';
return $xml;
}
/**
* 数组转XML辅助方法
*
* @param array $array
* @return string
*/
private static function arrayToXml(array $array)
{
$xml = '';
foreach ($array as $key => $value) {
if (is_int($key)) {
$key = 'item';
}
if ($key === '@attributes') {
foreach ($value as $attrKey => $attrValue) {
$xml = str_replace('<' . $attrKey . '>', '<' . $attrKey . ' ' . $attrValue . '>', $xml);
}
continue;
}
if (is_array($value)) {
$childXml = self::arrayToXml($value);
$xml .= '<' . $key . '>' . $childXml . '</' . $key . '>';
} else {
$xml .= '<' . $key . '>' . htmlspecialchars($value) . '</' . $key . '>';
}
}
return $xml;
}
/**
* 按值搜索并返回key
*
* @param array $array 数组
* @param mixed $value 要搜索的值
* @param bool $strict 严格比较
* @return mixed 找到的key或false
*/
public static function searchValue(array $array, $value, $strict = false)
{
return array_search($value, $array, $strict);
}
/**
* 获取数组最后一个元素
*
* @param array $array 数组
* @return mixed
*/
public static function last(array $array)
{
return end($array);
}
/**
* 获取数组第一个元素
*
* @param array $array 数组
* @return mixed
*/
public static function first(array $array)
{
return reset($array);
}
/**
* 随机打乱关联数组(保留key)
*
* @param array $array 数组
* @return array
*/
public static function shuffleAssoc(array $array)
{
$keys = array_keys($array);
shuffle($keys);
$result = [];
foreach ($keys as $key) {
$result[$key] = $array[$key];
}
return $result;
}
/**
* 数组元素求和(支持多维)
*
* @param array $array 数组
* @return int|float
*/
public static function sum(array $array)
{
$sum = 0;
array_walk_recursive($array, function ($value) use (&$sum) {
$sum += $value;
});
return $sum;
}
/**
* 数组交集(支持多维)
*
* @param array $array1 第一个数组
* @param array $array2 第二个数组
* @return array
*/
public static function intersect(array $array1, array $array2)
{
return array_uintersect($array1, $array2, function($a, $b) {
return strcmp(serialize($a), serialize($b));
});
}
}
使用示例
<?php
// 引入工具类
// require_once 'ArrayUtil.php';
// ============ 基本操作 ============
$user = [
'name' => '张三',
'age' => 25,
'address' => [
'city' => '北京',
'district' => '海淀区',
'detail' => [
'street' => '中关村大街'
]
]
];
// 获取值(支持点语法)
echo ArrayUtil::get($user, 'name'); // 张三
echo ArrayUtil::get($user, 'address.city'); // 北京
echo ArrayUtil::get($user, 'address.detail.street'); // 中关村大街
echo ArrayUtil::get($user, 'email', '默认邮箱'); // 默认邮箱
// 设置值(支持点语法)
$newUser = [];
ArrayUtil::set($newUser, 'address.city', '上海');
ArrayUtil::set($newUser, 'address.code', '200000');
// 检查是否存在
var_dump(ArrayUtil::has($user, 'address.city')); // true
var_dump(ArrayUtil::has($user, 'phone')); // false
// ============ 数据处理 ============
$items = [
['id' => 1, 'name' => '商品A', 'price' => 100, 'category' => '电子产品'],
['id' => 2, 'name' => '商品B', 'price' => 200, 'category' => '服装'],
['id' => 3, 'name' => '商品C', 'price' => 150, 'category' => '电子产品'],
['id' => 4, 'name' => '商品D', 'price' => 80, 'category' => '食品'],
['id' => 5, 'name' => '商品E', 'price' => 300, 'category' => '电子产品'],
];
// 排序
$byPrice = ArrayUtil::orderBy($items, 'price', 'DESC');
$byCategoryAndPrice = ArrayUtil::orderBy($items, ['category' => 'ASC', 'price' => 'DESC']);
// 分组
$categoryGroup = ArrayUtil::groupBy($items, 'category');
$priceGroup = ArrayUtil::groupBy($items, function($item) {
return $item['price'] > 150 ? '高价' : '低价';
});
// 提取字段
$names = ArrayUtil::pluck($items, 'name');
$productInfo = ArrayUtil::pluck($items, ['id', 'name', 'price']);
// 条件筛选
$expensiveItems = ArrayUtil::where($items, ['price' => ['gt' => 150]]);
$electronicItems = ArrayUtil::where($items, ['category' => '电子产品']);
$combinedFilter = ArrayUtil::where($items, [
'category' => '电子产品',
'price' => ['lte' => 200]
]);
// 分页
$page1 = ArrayUtil::paginate($items, 1, 2);
$page2 = ArrayUtil::paginate($items, 2, 2);
// 去重
$mainItems = [
['id' => 1, 'name' => '商品A'],
['id' => 2, 'name' => '商品A'],
['id' => 3, 'name' => '商品B'],
];
$uniqueItems = ArrayUtil::distinct($mainItems, 'name');
// ============ 高级操作 ============
// 扁平化
$nestedArray = [
'a' => 1,
'b' => ['c' => 2, 'd' => ['e' => 3]],
'f' => 4
];
$flattened = ArrayUtil::flatten($nestedArray);
print_r($flattened);
// 输出: ['a' => 1, 'b.c' => 2, 'b.d.e' => 3, 'f' => 4]
// 反转扁平化
$unflattened = ArrayUtil::unflatten($flattened);
print_r($unflattened);
// 数组转XML
$xmlData = [
'user' => ['name' => '张三', 'age' => 25],
'items' => [['id' => 1], ['id' => 2]]
];
$xml = ArrayUtil::toXml($xmlData, 'response');
echo $xml;
// 其他工具方法
$numbers = [5, 3, 8, 1, 9];
echo ArrayUtil::sum($numbers); // 26
echo ArrayUtil::first($numbers); // 5
echo ArrayUtil::last($numbers); // 9
echo ArrayUtil::searchValue($numbers, 8); // 2
$shuffled = ArrayUtil::shuffleAssoc($numbers);
print_r($shuffled);
扩展版本(更完整)
<?php
/**
* 扩展的数组工具类
* 增加更多实用功能
*/
class ExtendedArrayUtil extends ArrayUtil
{
/**
* 递归合并数组(更深层次的合并)
*
* @param array $array1 第一个数组
* @param array $array2 第二个数组
* @return array
*/
public static function deepMerge(array $array1, array $array2)
{
foreach ($array2 as $key => $value) {
if (isset($array1[$key]) && is_array($array1[$key]) && is_array($value)) {
$array1[$key] = self::deepMerge($array1[$key], $value);
} else {
$array1[$key] = $value;
}
}
return $array1;
}
/**
* 数组转对象
*
* @param array $array 数组
* @return object
*/
public static function toObject(array $array)
{
return json_decode(json_encode($array));
}
/**
* 对象转数组
*
* @param object $object 对象
* @return array
*/
public static function fromObject($object)
{
return json_decode(json_encode($object), true);
}
/**
* 移除数组中的空值(null, '', false, [])
*
* @param array $array 数组
* @return array
*/
public static function removeEmpty(array $array)
{
return array_filter($array, function($value) {
return !is_null($value) && $value !== '' && $value !== false && $value !== [];
});
}
/**
* 将数组转为查询字符串
*
* @param array $array 数组
* @return string
*/
public static function toQueryString(array $array)
{
$flattened = self::flatten($array);
$pairs = [];
foreach ($flattened as $key => $value) {
$pairs[] = urlencode($key) . '=' . urlencode($value);
}
return implode('&', $pairs);
}
/**
* 从查询字符串解析为数组
*
* @param string $queryString 查询字符串
* @return array
*/
public static function fromQueryString($queryString)
{
parse_str($queryString, $result);
return $result;
}
/**
* 在两个数组中查找差异(支持多维)
*
* @param array $array1 第一个数组
* @param array $array2 第二个数组
* @return array
*/
public static function diff(array $array1, array $array2)
{
$result = [];
// 查找在第一个数组但不在第二个数组中的元素
foreach ($array1 as $key => $value) {
if (!isset($array2[$key])) {
$result['only_in_first'][$key] = $value;
} elseif (is_array($value) && is_array($array2[$key])) {
$diff = self::diff($value, $array2[$key]);
if (!empty($diff)) {
$result['different'][$key] = $diff;
}
} elseif ($value != $array2[$key]) {
$result['different'][$key] = [
'first' => $value,
'second' => $array2[$key]
];
}
}
// 查找在第二个数组但不在第一个数组中的元素
foreach ($array2 as $key => $value) {
if (!isset($array1[$key])) {
$result['only_in_second'][$key] = $value;
}
}
return $result;
}
/**
* 生成指定范围的数字数组
*
* @param int $start 开始值
* @param int $end 结束值
* @param int $step 步长
* @return array
*/
public static function range($start, $end, $step = 1)
{
return range($start, $end, $step);
}
/**
* 数组转CSV字符串
*
* @param array $array 二维数组
* @param string $delimiter 分隔符
* @return string
*/
public static function toCsv(array $array, $delimiter = ',')
{
$output = '';
$firstRow = true;
foreach ($array as $row) {
if (!$firstRow) {
$output .= "\n";
}
$output .= implode($delimiter, array_map(function($value) {
return '"' . str_replace('"', '""', $value) . '"';
}, $row));
$firstRow = false;
}
return $output;
}
/**
* 数组转JSON字符串(带格式化和错误处理)
*
* @param array $array 数组
* @param bool $prettyPrint 是否格式化
* @return string|false
*/
public static function toJson(array $array, $prettyPrint = false)
{
$flags = JSON_UNESCAPED_UNICODE;
if ($prettyPrint) {
$flags |= JSON_PRETTY_PRINT;
}
$json = json_encode($array, $flags);
// 处理编码错误
if ($json === false && json_last_error() === JSON_ERROR_UTF8) {
$array = self::recursiveUtf8Encode($array);
$json = json_encode($array, $flags);
}
return $json;
}
/**
* 递归处理UTF-8编码
*
* @param array $array 数组
* @return array
*/
private static function recursiveUtf8Encode(array $array)
{
foreach ($array as $key => $value) {
if (is_array($value)) {
$array[$key] = self::recursiveUtf8Encode($value);
} elseif (is_string($value)) {
$array[$key] = utf8_encode($value);
}
}
return $array;
}
/**
* 数组替换占位符
*
* @param array $array 数组
* @param string $pattern 占位符模式,如 {name}
* @return array
*/
public static function replacePlaceholders(array $array, $placeholderPattern = '/{(.*?)}/')
{
$result = [];
array_walk_recursive($array, function($value, $key) use (&$result) {
if (is_string($value)) {
$value = preg_replace_callback($placeholderPattern, function($matches) use (&$result) {
return $result[$matches[1]] ?? $matches[0];
}, $value);
}
$result[$key] = $value;
});
return $result;
}
/**
* 数组统计(最大值、最小值、平均值、中位数)
*
* @param array $array 一维数组
* @return array
*/
public static function statistics(array $array)
{
if (empty($array)) {
return [];
}
sort($array);
$count = count($array);
$middle = floor($count / 2);
return [
'max' => max($array),
'min' => min($array),
'avg' => array_sum($array) / $count,
'median' => ($count % 2) ? $array[$middle] : (($array[$middle - 1] + $array[$middle]) / 2),
'count' => $count,
'sum' => array_sum($array),
];
}
/**
* 建立树形结构
*
* @param array $items 数据项列表
* @param int $parentId 父级ID
* @param string $idField ID字段名
* @param string $parentField 父级ID字段名
* @param string $childrenField 子级字段名
* @return array
*/
public static function buildTree(
array $items,
$parentId = 0,
$idField = 'id',
$parentField = 'parent_id',
$childrenField = 'children'
) {
$tree = [];
$itemsByParent = [];
foreach ($items as $item) {
$itemsByParent[$item[$parentField]][] = $item;
}
$build = function ($parentId) use (&$build, &$itemsByParent, $idField, $childrenField) {
$branch = [];
if (isset($itemsByParent[$parentId])) {
foreach ($itemsByParent[$parentId] as $item) {
$item[$childrenField] = $build($item[$idField]);
$branch[] = $item;
}
}
return $branch;
};
return $build($parentId);
}
}
这个工具类包含了:
- 基本操作:获取、设置、检查、删除(支持点语法)
- 数据处理:排序、分组、筛选、分页、去重
- 高级功能:扁平化、树形构建、XML转换、CSV转换
- 实用工具:统计、差异比较、占位符替换等
使用这个工具类可以大大提高PHP数组操作的效率和代码的可读性。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播