数组创建与语法
概述
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。使用 ?? 运算符安全访问。
最佳实践
- 使用短数组语法 []:PHP 5.4+ 统一使用
- PHP 7.1+ 使用短解构:
[$a, $b] = $arr - PHP 8.1+ 使用字符串键解构:
['key' => $val] = $arr - 避免键名混合类型:保持一致性
- 多维数组用 array_column:提取列数据