PHP 数组详解

数组是 PHP 中最重要的数据结构之一,它允许在单个变量中存储多个值,是处理数据集合的强大工具。

什么是数组?

数组是一种特殊变量,可以在单个变量中存储多个值。与使用多个独立变量相比,数组提供了更高效的数据管理方式。

数组的优势:

  • 在单个变量中组织相关数据
  • 支持快速的数据访问和操作
  • 提供丰富的内置函数进行处理
  • 支持多种数据类型混合存储
  • 便于循环遍历和批量操作

数组 vs 独立变量

<?php
// 使用独立变量(不推荐用于相关数据)
$car1 = "Volvo";
$car2 = "BMW";
$car3 = "Toyota";

// 使用数组(推荐方式)
$cars = array("Volvo", "BMW", "Toyota");
echo "我喜欢 " . $cars[0] . ", " . $cars[1] . " 和 " . $cars[2] . "。";
?>

PHP 数组类型

PHP 支持三种主要类型的数组:

索引数组

使用数字索引的数组

$array[0], $array[1]...

关联数组

使用字符串键名的数组

$array['name'], $array['age']...

多维数组

包含一个或多个数组的数组

$array[0]['name']...

创建数组

PHP 提供了多种创建数组的方式:

使用 array() 函数

传统创建方式

<?php
// 创建空数组
$emptyArray = array();

// 创建索引数组
$fruits = array("苹果", "香蕉", "橙子");

// 创建关联数组
$person = array(
    "name" => "张三",
    "age" => 25,
    "city" => "北京"
);

// 创建混合数组
$mixed = array(1, "hello", 3.14, true);
?>

使用短数组语法(PHP 5.4+)

现代创建方式

<?php
// 使用方括号语法
$emptyArray = [];

// 索引数组
$colors = ["红色", "绿色", "蓝色"];

// 关联数组
$user = [
    "username" => "john_doe",
    "email" => "john@example.com",
    "active" => true
];

// 动态添加元素
$numbers = [];
$numbers[] = 1;
$numbers[] = 2;
$numbers[] = 3;
?>

索引数组

索引数组使用数字作为键名,键名从 0 开始自动分配。

索引数组基础

<?php
// 创建索引数组
$cars = array("Volvo", "BMW", "Toyota");

// 访问数组元素
echo "第一辆车: " . $cars[0] . "<br>";
echo "第二辆车: " . $cars[1] . "<br>";
echo "第三辆车: " . $cars[2] . "<br>";

// 修改数组元素
$cars[1] = "Mercedes";
echo "修改后第二辆车: " . $cars[1] . "<br>";

// 添加新元素
$cars[] = "Honda";
echo "新增车辆: " . $cars[3] . "<br>";
?>

获取数组长度

使用 count() 函数获取数组的元素数量:

count() 函数示例

<?php
$fruits = array("苹果", "香蕉", "橙子", "葡萄");
$arrayLength = count($fruits);

echo "水果数组包含 " . $arrayLength . " 个元素<br>";

// 在实际应用中使用
if (count($fruits) > 0) {
    echo "数组不为空<br>";
} else {
    echo "数组为空<br>";
}
?>

遍历索引数组

使用 for 循环遍历

<?php
$numbers = array(10, 20, 30, 40, 50);
$length = count($numbers);

echo "数字数组: <br>";
for ($i = 0; $i < $length; $i++) {
    echo "索引 $i: " . $numbers[$i] . "<br>";
}

echo "<br>";

// 使用 foreach 循环(推荐)
echo "使用 foreach 遍历: <br>";
foreach ($numbers as $number) {
    echo "数字: $number<br>";
}

echo "<br>";

// 获取索引和值
foreach ($numbers as $index => $value) {
    echo "索引 $index 的值是: $value<br>";
}
?>

关联数组

关联数组使用字符串作为键名,可以创建更有意义的键值对数据结构。

关联数组基础

<?php
// 创建关联数组
$person = array(
    "name" => "李四",
    "age" => 30,
    "city" => "上海",
    "email" => "lisi@example.com"
);

// 访问元素
echo "姓名: " . $person["name"] . "<br>";
echo "年龄: " . $person["age"] . "<br>";
echo "城市: " . $person["city"] . "<br>";

// 修改元素
$person["age"] = 31;
echo "更新后年龄: " . $person["age"] . "<br>";

// 添加新元素
$person["country"] = "中国";
echo "国家: " . $person["country"] . "<br>";
?>

遍历关联数组

使用 foreach 遍历关联数组

<?php
$student = array(
    "学号" => "2023001",
    "姓名" => "王五",
    "专业" => "计算机科学",
    "年级" => "大三",
    "GPA" => 3.8
);

echo "学生信息: <br>";
foreach ($student as $key => $value) {
    echo "$key: $value<br>";
}

echo "<br>";

// 只获取值
foreach ($student as $value) {
    echo "值: $value<br>";
}

// 实际应用:配置信息
$config = [
    "site_name" => "我的网站",
    "admin_email" => "admin@example.com",
    "debug_mode" => true,
    "max_upload_size" => 5242880
];

echo "<br>网站配置: <br>";
foreach ($config as $setting => $value) {
    echo "$setting: " . (is_bool($value) ? ($value ? '是' : '否') : $value) . "<br>";
}
?>

多维数组

多维数组是包含一个或多个数组的数组,用于表示复杂的数据结构。

二维数组

创建和访问二维数组

<?php
// 二维数组:学生列表
$students = array(
    array("张三", 20, "计算机"),
    array("李四", 21, "数学"),
    array("王五", 19, "物理")
);

// 访问元素
echo "第一个学生: " . $students[0][0] . "<br>";
echo "年龄: " . $students[0][1] . "<br>";
echo "专业: " . $students[0][2] . "<br>";

echo "<br>";

// 使用关联数组的二维数组
$employees = array(
    "emp1" => array(
        "name" => "赵六",
        "position" => "开发工程师",
        "salary" => 8000
    ),
    "emp2" => array(
        "name" => "钱七",
        "position" => "产品经理",
        "salary" => 12000
    )
);

echo $employees["emp1"]["name"] . " 的职位是: " . $employees["emp1"]["position"] . "<br>";
?>

遍历多维数组

嵌套循环遍历

<?php
// 产品分类数据
$products = array(
    "电子产品" => array(
        "手机" => array("iPhone", "Samsung", "华为"),
        "电脑" => array("MacBook", "ThinkPad", "Dell")
    ),
    "服装" => array(
        "男装" => array("衬衫", "裤子", "外套"),
        "女装" => array("裙子", "上衣", "裤子")
    )
);

// 遍历多维数组
foreach ($products as $category => $subcategories) {
    echo "<h3>$category</h3>";

    foreach ($subcategories as $subcategory => $items) {
        echo "<strong>$subcategory:</strong> ";
        echo implode(", ", $items) . "<br>";
    }
    echo "<br>";
}

// 表格形式显示数据
$studentScores = [
    ["姓名", "语文", "数学", "英语"],
    ["张三", 85, 92, 78],
    ["李四", 90, 88, 95],
    ["王五", 76, 85, 80]
];

echo "<table border='1' style='border-collapse: collapse;'>";
foreach ($studentScores as $row) {
    echo "<tr>";
    foreach ($row as $cell) {
        echo "<td style='padding: 5px;'>$cell</td>";
    }
    echo "</tr>";
}
echo "</table>";
?>

常用数组函数

数组操作函数

基本数组操作

<?php
// array_push() - 添加一个或多个元素到数组末尾
$stack = array("orange", "banana");
array_push($stack, "apple", "raspberry");
print_r($stack);
echo "<br>";

// array_pop() - 删除数组最后一个元素
$fruit = array_pop($stack);
echo "删除的元素: $fruit<br>";
print_r($stack);
echo "<br>";

// array_shift() - 删除数组第一个元素
$first = array_shift($stack);
echo "删除的第一个元素: $first<br>";
print_r($stack);
echo "<br>";

// array_unshift() - 在数组开头插入一个或多个元素
array_unshift($stack, "mango", "pineapple");
print_r($stack);
echo "<br>";

// array_merge() - 合并一个或多个数组
$array1 = array("color" => "red", 2, 4);
$array2 = array("a", "b", "color" => "green", "shape" => "trapezoid", 4);
$result = array_merge($array1, $array2);
print_r($result);
echo "<br>";
?>

数组搜索和过滤

搜索和过滤操作

<?php
// in_array() - 检查数组中是否存在某个值
$os = array("Mac", "NT", "Irix", "Linux");
if (in_array("Irix", $os)) {
    echo "找到 Irix<br>";
}

// array_search() - 在数组中搜索给定的值,返回键名
$array = array(0 => 'blue', 1 => 'red', 2 => 'green', 3 => 'red');
$key = array_search('green', $array);
echo "green 的键是: $key<br>";

// array_filter() - 用回调函数过滤数组中的元素
$numbers = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
$even = array_filter($numbers, function($num) {
    return $num % 2 == 0;
});
echo "偶数: ";
print_r($even);
echo "<br>";

// array_map() - 将回调函数作用到给定数组的元素上
$numbers = array(1, 2, 3, 4, 5);
$squares = array_map(function($n) {
    return $n * $n;
}, $numbers);
echo "平方数: ";
print_r($squares);
echo "<br>";
?>

数组排序

各种排序方法

<?php
// sort() - 对数组排序(升序)
$numbers = array(4, 6, 2, 22, 11);
sort($numbers);
echo "升序排序: ";
print_r($numbers);
echo "<br>";

// rsort() - 对数组逆向排序(降序)
rsort($numbers);
echo "降序排序: ";
print_r($numbers);
echo "<br>";

// asort() - 对关联数组按照值升序排序
$age = array("Peter" => 35, "Ben" => 37, "Joe" => 43);
asort($age);
echo "按值升序: ";
print_r($age);
echo "<br>";

// ksort() - 对关联数组按照键升序排序
ksort($age);
echo "按键升序: ";
print_r($age);
echo "<br>";
?>

实际应用场景

表单数据处理

处理用户提交的数据

<?php
// 模拟表单提交数据
$_POST = [
    "username" => "john_doe",
    "email" => "john@example.com",
    "password" => "secret123",
    "interests" => ["编程", "阅读", "运动"]
];

// 处理表单数据
function processFormData($data) {
    $processed = [];

    // 基本验证和清理
    $processed['username'] = trim($data['username']);
    $processed['email'] = filter_var($data['email'], FILTER_VALIDATE_EMAIL);

    // 处理数组字段
    if (isset($data['interests']) && is_array($data['interests'])) {
        $processed['interests'] = array_map('trim', $data['interests']);
        $processed['interests_count'] = count($data['interests']);
    }

    return $processed;
}

$result = processFormData($_POST);
echo "处理后的数据: <br>";
print_r($result);
?>

配置管理系统

使用数组管理配置

<?php
// 应用配置数组
$config = [
    'database' => [
        'host' => 'localhost',
        'name' => 'myapp_db',
        'user' => 'app_user',
        'pass' => 'secure_password'
    ],
    'app' => [
        'name' => '我的应用',
        'version' => '1.0.0',
        'debug' => true,
        'timezone' => 'Asia/Shanghai'
    ],
    'features' => [
        'user_registration' => true,
        'email_verification' => false,
        'social_login' => ['google', 'facebook']
    ]
];

// 访问配置
echo "应用名称: " . $config['app']['name'] . "<br>";
echo "数据库主机: " . $config['database']['host'] . "<br>";
echo "支持的社会化登录: " . implode(', ', $config['features']['social_login']) . "<br>";

// 配置验证函数
function validateConfig($config) {
    $errors = [];

    if (empty($config['database']['host'])) {
        $errors[] = "数据库主机不能为空";
    }

    if (!in_array($config['app']['timezone'], timezone_identifiers_list())) {
        $errors[] = "无效的时区设置";
    }

    return $errors;
}

$validationErrors = validateConfig($config);
if (empty($validationErrors)) {
    echo "配置验证通过<br>";
} else {
    echo "配置错误: " . implode('; ', $validationErrors) . "<br>";
}
?>

数据统计和分析

数组数据统计分析

<?php
// 学生成绩数据
$scores = [
    '张三' => [85, 92, 78],
    '李四' => [90, 88, 95],
    '王五' => [76, 85, 80],
    '赵六' => [92, 96, 88]
];

// 计算每个学生的平均分
$averages = [];
foreach ($scores as $student => $grades) {
    $averages[$student] = array_sum($grades) / count($grades);
}

// 按平均分排序
arsort($averages);

echo "学生平均分排名: <br>";
$rank = 1;
foreach ($averages as $student => $average) {
    printf("%d. %s: %.2f<br>", $rank++, $student, $average);
}

// 统计各科目平均分
$subjectAverages = [];
foreach ($scores as $grades) {
    foreach ($grades as $index => $grade) {
        if (!isset($subjectAverages[$index])) {
            $subjectAverages[$index] = [];
        }
        $subjectAverages[$index][] = $grade;
    }
}

echo "<br>各科目平均分: <br>";
$subjects = ['语文', '数学', '英语'];
foreach ($subjectAverages as $index => $grades) {
    $average = array_sum($grades) / count($grades);
    echo $subjects[$index] . ": " . round($average, 2) . "<br>";
}
?>

PHP 7/8 数组新特性

PHP 7.1 数组解构

使用列表解构数组

<?php
// PHP 7.1+ 数组解构
$data = ['John', 'Doe', 30];

// 传统方式
list($firstName, $lastName, $age) = $data;
echo "$firstName $lastName, $age 岁<br>";

// PHP 7.1+ 短语法
[$firstName, $lastName, $age] = $data;
echo "$firstName $lastName, $age 岁<br>";

// 跳过某些元素
[, , $age] = $data;
echo "年龄: $age<br>";

// 关联数组解构(PHP 7.1+)
$user = ['name' => 'Alice', 'email' => 'alice@example.com'];
['name' => $name, 'email' => $email] = $user;
echo "姓名: $name, 邮箱: $email<br>";
?>

PHP 8 数组函数改进

PHP 8 新特性

<?php
// array_contains() 类似功能(PHP 8.1+ str_contains 用于字符串)
$haystack = ["apple", "banana", "cherry"];

// PHP 8+ 使用 in_array 的严格模式
if (in_array("banana", $haystack, true)) {
    echo "找到 banana<br>";
}

// 数组展开运算符(PHP 7.4+)
$parts = ['apple', 'pear'];
$fruits = ['banana', 'orange', ...$parts, 'watermelon'];
echo "合并后的水果: " . implode(', ', $fruits) . "<br>";

// 数组解构与展开结合
$first = [1, 2];
$second = [3, 4];
$merged = [...$first, ...$second];
echo "合并数组: " . implode(', ', $merged) . "<br>";
?>

最佳实践和性能优化

数组使用最佳实践:

  • 根据数据特性选择合适的数组类型(索引、关联或多维)
  • 使用有意义的键名提高代码可读性
  • 避免在循环中重复计算数组长度
  • 使用适当的数组函数替代手动循环操作
  • 对于大型数组,考虑使用生成器或分批处理
  • 使用 isset() 检查数组元素是否存在,而不是直接访问

性能优化示例

<?php
// 优化前:在循环中重复计算
$items = range(1, 1000);
for ($i = 0; $i < count($items); $i++) {
    // 处理逻辑
}

// 优化后:预先计算长度
$items = range(1, 1000);
$count = count($items);
for ($i = 0; $i < $count; $i++) {
    // 处理逻辑
}

// 更好的方式:使用 foreach
foreach ($items as $item) {
    // 处理逻辑
}

// 安全访问数组元素
$config = ['host' => 'localhost'];

// 不安全
// $port = $config['port']; // 可能产生警告

// 安全方式
$port = $config['port'] ?? 3306; // PHP 7+ 空合并运算符
$port = isset($config['port']) ? $config['port'] : 3306; // 传统方式

echo "端口: $port<br>";
?>

总结

  • 数组是在单个变量中存储多个值的强大数据结构
  • PHP 支持索引数组、关联数组和多维数组
  • 可以使用 array() 函数或短数组语法 [] 创建数组
  • 使用 count() 获取数组长度,使用循环遍历数组元素
  • PHP 提供了丰富的数组函数用于搜索、排序、过滤等操作
  • 多维数组用于表示复杂的数据结构
  • PHP 7/8 引入了数组解构、展开运算符等新特性
  • 遵循最佳实践可以提高代码性能和可维护性

完整的 PHP 数组参考手册

如需查看所有数组函数的完整参考手册,请访问我们的 PHP Array 参考手册

该参考手册提供了每个函数的详细描述、参数说明和应用实例!