Skip to content

数组创建与语法

概述

PHP 数组是一种灵活的有序映射数据结构,支持索引数组和关联数组。PHP 5.4+ 引入了短数组语法 [],PHP 7.1+ 支持数组解构,PHP 8.1+ 支持字符串键解构。本章全面讲解数组的创建方式和语法规则。

基础概念

数组类型与语法演进

类型示例键类型
索引数组['a', 'b', 'c']自动递增整数
关联数组['name' => 'Alice']字符串
多维数组[[1,2],[3,4]]混合
特性版本旧语法新语法
短数组PHP 5.4+array(1, 2)[1, 2]
短解构PHP 7.1+list($a, $b)[$a, $b]
展开运算符PHP 7.4+array_merge()...$arr
字符串键解构PHP 8.1+不支持['k' => $v] = $arr

语法与代码

索引数组

php
<?php

declare(strict_types=1);

// PHP 5.4+ 短数组语法(推荐)
$fruits = ['apple', 'banana', 'cherry'];

echo $fruits[0];  // apple
echo $fruits[1];  // banana

// 指定索引
$colors = [0 => 'red', 1 => 'green', 2 => 'blue'];

// 跳跃索引
$data = [0 => 'a', 5 => 'b', 10 => 'c'];

// 混合指定和自动索引
$mixed = [3 => 'three', 'four', 'five'];
// [3 => 'three', 4 => 'four', 5 => 'five']

关联数组

php
<?php

declare(strict_types=1);

$user = [
    'name' => 'Alice',
    'email' => 'alice@example.com',
    'age' => 30,
];

echo $user['name'];   // Alice

// 键转换规则:
// - 字符串 '1' 转为整数 1
// - 浮点数键截断为整数
// - true = 1, false = 0, null = ''

多维数组

php
<?php

declare(strict_types=1);

$users = [
    ['name' => 'Alice', 'age' => 30],
    ['name' => 'Bob', 'age' => 25],
];

echo $users[0]['name'];  // Alice

// 三维数组
$grades = [
    'class1' => [
        'Alice' => ['math' => 95, 'english' => 88],
    ],
];
echo $grades['class1']['Alice']['math'];  // 95

数组解构(PHP 7.1+)

php
<?php

declare(strict_types=1);

$colors = ['red', 'green', 'blue'];

// PHP 7.1+ 短语法解构
[$r, $g, $b] = $colors;
echo $r;  // red

// 跳过元素
[, $second, $third] = $colors;
echo $second;  // green

// 交换变量
$a = 'hello'; $b = 'world';
[$b, $a] = [$a, $b];
echo $a;  // world

// PHP 8.1+ 字符串键解构
$user = ['name' => 'Alice', 'age' => 30, 'email' => 'a@b.com'];
['name' => $name, 'age' => $age] = $user;
echo $name;  // Alice

// 选择性解构
['name' => $name, 'role' => $role] = $user + ['role' => 'guest'];
echo $role;  // guest

数组赋值与追加

php
<?php

declare(strict_types=1);

$arr = [];
$arr[0] = 'first';
$arr[1] = 'second';
$arr[] = 'third';  // 自动追加(索引为 2)

// 关联数组追加
$arr = [];
$arr['name'] = 'Alice';
$arr['email'] = 'alice@example.com';

// += 追加关联元素
$config = ['debug' => true];
$config += ['cache' => true, 'timeout' => 30];
// ['debug' => true, 'cache' => true, 'timeout' => 30]

详细说明

数组键的自动转换规则

php
<?php

declare(strict_types=1);

// 字符串数字键被转换为整数
$arr = [
    1    => 'a',
    '1'  => 'b',  // 覆盖上一个(键都是 1)
    true => 'c',  // true = 1,再次覆盖
    false => 'd', // false = 0
    null  => 'e',  // null = ''
];

print_r($arr);
// [1 => 'c', 0 => 'd', '' => 'e']

键名冲突

字符串数字 '1' 会被转换为整数 1,可能导致意外覆盖。避免混合使用字符串数字键和整数键。

实战示例

从数据库结果构建数组

php
<?php

declare(strict_types=1);

$records = [
    ['id' => 1, 'name' => 'Alice', 'role' => 'admin'],
    ['id' => 2, 'name' => 'Bob', 'role' => 'user'],
    ['id' => 3, 'name' => 'Charlie', 'role' => 'user'],
];

// 以 id 为键
$byId = array_column($records, null, 'id');

// 提取选项列表
$options = array_column($records, 'name', 'id');
// [1 => 'Alice', 2 => 'Bob', 3 => 'Charlie']

// 分组
$byRole = [];
foreach ($records as $r) {
    $byRole[$r['role']][] = $r['name'];
}
// ['admin' => ['Alice'], 'user' => ['Bob', 'Charlie']]

配置文件数组

php
<?php

declare(strict_types=1);

return [
    'app' => [
        'name' => 'MyApp',
        'env' => 'production',
        'debug' => false,
    ],
    'database' => [
        'driver' => 'mysql',
        'host' => 'localhost',
        'port' => 3306,
    ],
    'cache' => [
        'default' => 'redis',
        'stores' => [
            'redis' => ['host' => '127.0.0.1', 'port' => 6379],
            'file' => ['path' => '/tmp/cache'],
        ],
    ],
];

数组常量与枚举(PHP 8.2+)

php
<?php

declare(strict_types=1);

// PHP 8.2+ 常量表达式中的数组
const DEFAULT_CONFIG = ['debug' => false, 'cache' => true];

// 使用常量数组
$config = DEFAULT_CONFIG + ['debug' => true];
// ['debug' => true, 'cache' => true]

// 枚举中返回数组(PHP 8.1+)
enum HttpMethod: string
{
    case Get = 'GET';
    case Post = 'POST';
    case Put = 'PUT';
    case Delete = 'DELETE';

    /**
     * @return string[]
     */
    public function allowedContentTypes(): array
    {
        return match ($this) {
            self::Get => ['application/json', 'text/html'],
            self::Post => ['application/json', 'multipart/form-data'],
            self::Put => ['application/json'],
            self::Delete => ['application/json'],
        };
    }
}

echo implode(', ', HttpMethod::Post->allowedContentTypes());

不可变数组(Immutable Array)

php
<?php

declare(strict_types=1);

// 通过 final class 实现不可变数组
final class ReadOnlyArray
{
    private array $data;

    public function __construct(array $data)
    {
        $this->data = $data;
    }

    public function get(string $key, mixed $default = null): mixed
    {
        return $this->data[$key] ?? $default;
    }

    public function has(string $key): bool
    {
        return array_key_exists($key, $this->data);
    }

    public function toArray(): array
    {
        return $this->data;
    }

    public function count(): int
    {
        return count($this->data);
    }

    public function keys(): array
    {
        return array_keys($this->data);
    }

    public function values(): array
    {
        return array_values($this->data);
    }
}

$config = new ReadOnlyArray(['host' => 'localhost', 'port' => 3306]);
echo $config->get('host');     // localhost
echo $config->get('timeout'); // null(默认值)

数组字面量的 PHP 版本兼容

php
<?php

declare(strict_types=1);

// PHP 5.3 - 必须使用 array()
$arr = array('a', 'b', 'c');
$arr = array('key' => 'value');

// PHP 5.4+ - 短数组语法
$arr = ['a', 'b', 'c'];
$arr = ['key' => 'value'];

// PHP 5.6+ - 常量表达式中的数组
const ARR = [1, 2, 3];

// PHP 7.1+ - 短数组解构
[$a, $b, $c] = [1, 2, 3];

// PHP 7.4+ - 展开运算符
$merged = [...[1, 2], ...[3, 4]];

// PHP 8.1+ - 字符串键解构
['key' => $value] = ['key' => 'test'];

// PHP 8.2+ - 更多常量表达式
const DEFAULTS = ['a' => 1, 'b' => 2];

向后兼容

如果项目需要兼容 PHP 5.3,使用 array() 语法。如果最低要求 PHP 5.4+,统一使用 []

数组导出

php
<?php

declare(strict_types=1);

// var_export - 生成可执行的 PHP 代码
$config = ['debug' => false, 'cache' => true, 'timeout' => 30];
$exported = var_export($config, true);
// "array (\n  'debug' => false,\n  'cache' => true,\n  'timeout' => 30,\n)"

// 写入配置文件缓存
file_put_contents('/tmp/config_cache.php', '<?php return ' . $exported . ';');

// 读取缓存配置
$cachedConfig = require '/tmp/config_cache.php';

注意事项

自增索引

自动索引基于当前最大整数键 + 1。手动设置很大的整数键后,$arr[] 追加会从该值开始。

多维数组访问

PHP 8.0+ 访问不存在的中间层级会产生 Warning。使用 ?? 运算符安全访问。

最佳实践

  1. 使用短数组语法 []:PHP 5.4+ 统一使用
  2. PHP 7.1+ 使用短解构[$a, $b] = $arr
  3. PHP 8.1+ 使用字符串键解构['key' => $val] = $arr
  4. 避免键名混合类型:保持一致性
  5. 多维数组用 array_column:提取列数据

参考链接