数组
数组是在程序设计中,为了处理方便, 把若干变量按有序的形式组织起来的一种形式。
按数组键值类型的不同,数组又可分为:数值索引数组、字符关联数组。
数组中有几个索引值就被称为几维数组。
数组分类
在PHP中有两种数组:索引数组和关联数组。
- 索引(indexed)数组的索引值是整数,以0开始。当通过位置来标识东西时用索引数组。
- 关联(associative)数组以字符串做为索引值,类似操作表。索引值为列名,用于访问列的数据
php
$arr = [1, 2, 3]; // 索引数组
$users = ['name' => 'admin', 'age' => 1]; // 关联数组读取数组元素
key - 从关联数组中取得键名
php
$arr = ['abc', 'xyz'];
echo key($arr); // 0current - 返回数组中的当前单元
php
$arr = ['abc', 'xyz'];
echo current($arr); // abcnext - 返回数组下一个值
将数组中的内部指针向下移动一位,并返回值。没有更多单元时返回 FALSE
php
$arr = ['abc', 'xyz'];
echo next($arr); // xyzprev - 返回数组上一个值
将数组的内部指针倒回一位,并返回值。没有更多单元时返回 FALSE
php
$arr = ['abc', 'xyz'];
var_dump(prev($arr)); // falsereset - 返回数组第一个元素
将内部指针指向数组中的第一个元素,并输出
php
$people = ['Peter', 'Joe', 'Glenn', 'Cleveland'];
echo current($people) . '<br/>'; // Peter
echo next($people) . '<br/>'; // Joe
echo reset($people); // Peter指针遍历
php
$users = [
['name' => '小明', 'age' => 22],
['name' => '张三', 'age' => 19],
['name' => '李四', 'age' => 34],
];
?>
<table border="1">
<tr>
<th>编号</th>
<th>姓名</th>
<th>年龄</th>
</tr>
<?php while ($user = current($users)): ?>
<tr>
<td><?php echo key($users) + 1 ?></td>
<td><?php echo $user['name'] ?></td>
<td><?php echo $user['age'] ?></td>
</tr>
<?php next($users); endwhile; ?>
</table>遍历数组
foreach
php
$array = [1, 2, 3];
foreach ($array as $key => $value) {
echo $key . '=>' . $value . '<br/>';
}list
- 把数组中的值赋给一组变量
php
$array = ['admin', 'foo@foo.com'];
list($name, $email) = $array;
echo $name . ' : ' . $email; // admin : foo@foo.com- 直接显示第三个
php
$array = ['zhangsan', 'lisi', 'wangwu'];
list(, , $name) = $array;
echo $name; // wangwu- 使用键名
php
$users = [
['name' => '小明', 'age' => 22],
['name' => '张三', 'age' => 19],
['name' => '李四', 'age' => 34],
];
while (list('name' => $name, 'age' => $age) = current($users)) {
echo "name: {$name} <br/>";
next($users);
}常用函数
array_push
将一个或多个单元压入数组的末尾,这是传址操作。
php
$users = ['user1', 'user2'];
array_push($users, 'user3');
print_r($users); // Array ( [0] => user1 [1] => user2 [2] => user3 )array_pop
弹出数组最后一个单元(出栈),这是传址操作。
php
$users = ['user1', 'user2'];
array_pop($users);
print_r($users); // Array ( [0] => user1 )array_shift
将数组开头的单元移出数组,这是传址操作。
php
$users = ['user1', 'user2'];
array_shift($users);
print_r($users); // Array ( [0] => user2 )array_unshift
在数组开头插入一个或多个单元
php
$users = ['user1', 'user2'];
array_unshift($users, 'user0');
print_r($users); // Array ( [0] => user0 [1] => user1 [2] => user2 )count
计算数组中的单元数目,或对象中的属性个数
php
$users = ['user1', 'user2'];
echo count($users); // 2array_count_values
统计数组中所有的值
php
$prices_per_day = ['单床房' => 198, '标准间' => 268, '大床房' => 198, 'VIP套房' => 368];
print_r(array_count_values($prices_per_day));
// AArray ( [198] => 2 [268] => 1 [368] => 1 )in_array
检查数组中是否存在某个值
php
$allowImageType = ['jpeg', 'jpg', 'png'];
$file = 'foo.txt';
$ext = strtolower(substr(strrchr($file, '.'), 1));
if (!in_array($ext, $allowImageType)) {
echo 'is wrong';
}array_key_exists
检查数组里是否有指定的键名或索引
php
$allowImageType = ['jpeg' => 100, 'jpg' => 200, 'png' => 300];
$file = 'foo.txt';
$ext = strtolower(substr(strrchr($file, '.'), 1));
if (!array_key_exists($ext, $allowImageType)) {
echo 'is wrong';
}array_keys
获取数组中所有的键名(返回数组)
php
$allowImageType = ['jpeg' => 100, 'jpg' => 200, 'png' => 300];
$file = 'foo.jpg';
$ext = strtolower(substr(strrchr($file, '.'), 1));
if (!in_array($ext, array_keys($allowImageType))) {
echo 'is wrong';
}array_filter
用回调函数过滤数组中的单元
php
$users = [
['name' => '张三', 'sex' => '男', 'age' => 20],
['name' => '李四', 'sex' => '女', 'age' => 33]
];
$result = array_filter($users, function ($user) {
return $user['sex'] == '男';
});
print_r($result);array_map
为数组的每个元素应用回调函数
php
$users = [
['name' => '张三', 'sex' => '男', 'age' => 20],
['name' => '李四', 'sex' => '女', 'age' => 33]
];
$result = array_map(function ($user) {
unset($user['age']);
return $user;
}, $users);
echo '<pre>';
print_r($result);获取所有会员名称
php
$users = [
['name' => '张三', 'sex' => '男', 'age' => 20],
['name' => '李四', 'sex' => '女', 'age' => 33]
];
$result = array_map(function ($user) {
return $user['name'];
}, $users);
echo '<pre>';
print_r($result);array_unique
移除数组中重复的值
实现数组中元素的唯一性。也就是去掉数组中重复的元素。不管是数字索引数组还是联合索引数组,都是以元素值为准。
php
$user = [
'real_name' => 'Token',
'nick_name' => 'Token',
'age' => 28,
];
// array_unique(array $array, int $flags = SORT_STRING): array
// 注意键名保留不变。如果指定了 flags 时存在多个相等的元素,会保留第一个相等的元素的键和值
var_dump(array_unique($user)); // 属性nick_name会被移除array_values
返回数组中所有的值
php
$users = [
['name' => '张三', 'sex' => '男', 'age' => 20],
['name' => '李四', 'sex' => '女', 'age' => 33]
];
$result = array_map(function ($user) {
return implode('-', array_values($user));
}, $users);
echo '<pre>';
print_r($result);array_merge
合并一个或多个数组
php
$array1 = [1, 2];
$array2 = [3, 4];
$array = array_merge($array1, $array2);
print_r($array); // Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 )关联数组中,相同键名,后面的会覆盖前面的
php
$array1 = ['host' => '127.0.0.1'];
$array2 = ['host' => 'localhost'];
$array = array_merge($array1, $array2);
print_r($array); // Array ( [host] => localhost )array_change_key_case
将数组中的所有键名修改为全大写或小写
php
//键名转大写
$database = [
'host' => 'localhost', 'port' => 3306
];
$result = array_change_key_case($database, CASE_UPPER);
print_r($result); // Array ( [HOST] => localhost [PORT] => 3306 )
//键名转小写
$database = [
'Host' => 'localhost', 'Port' => 3306
];
$result = array_change_key_case($database, CASE_LOWER);
print_r($result); // Array ( [host] => localhost [port] => 3306 )递归改变数组键名
php
$config = [
'database' => ['host' => 'localhost', 'port' => 3306, 'user' => 'root'],
'app' => ['name' => 'admin', 'url' => 'www.foo.com', 'app' => ['foo']]
];
function reset_array_change_key_case(array $data, int $type = CASE_UPPER): array
{
foreach ($data as $k => $v):
$action = $type == CASE_UPPER ? 'strtoupper' : 'strtolower';
unset($data[$k]);
$data[$action($k)] = is_array($v) ? reset_array_change_key_case($v, $type) : $v;
endforeach;
return $data;
}
echo '<pre>';
print_r(reset_array_change_key_case($config));递归改变数组值
php
$config = [
'database' => ['host' => 'localhost', 'port' => 3306, 'user' => 'root'],
'app' => ['name' => 'admin', 'url' => 'www.foo.com', 'app' => ['foo']]
];
function reset_array_change_value_case(array $data, int $type = CASE_UPPER): array
{
foreach ($data as $k => $v):
$action = $type == CASE_UPPER ? 'strtoupper' : 'strtolower';
$data[$k] = is_array($v) ? reset_array_change_value_case($v, $type) : $action($v);
endforeach;
return $data;
}
echo '<pre>';
print_r(reset_array_change_value_case($config));array_walk_recursive
对数组中的每个成员递归地应用用户函数,本函数会递归到更深层的数组中去。下面是改变数组键值的操作。
php
$config = [
'database' => ['host' => 'localhost', 'port' => 3306, 'user' => 'root'],
'app' => ['name' => 'admin', 'url' => 'www.foo.com', 'app' => ['foo']]
];
function change_array_value(array $data, int $type = CASE_UPPER): array
{
array_walk_recursive($data, function (&$value, $key, $type) {
$action = $type == CASE_UPPER ? 'strtoupper' : 'strtolower';
$value = $action($value);
}, $type);
return $data;
}
echo '<pre>';
print_r(change_array_value($config));var_export
输出或返回一个变量的字符串表示,第二个参数为 TRUE 时返回字符串。
提示
此场景适合用于,首次站点部署,引导页系统配置后,生成配置文件
php
<?php
/**
* 把array()转为[]显示
* @param $expression array 数组
* @param false $return bool 是否输出,TRUE 输出 FALSE 打印
* @return string|string[]|null
*/
function varExport($expression, $return = FALSE)
{
$export = var_export($expression, TRUE);
$patterns = [
"/array \(/" => '[',
"/^([ ]*)\)(,?)$/m" => '$1]$2',
"/=>[ ]?\n[ ]+\[/" => '=> [',
"/([ ]*)(\'[^\']+\') => ([\[\'])/" => '$1$2 => $3',
];
$export = preg_replace(array_keys($patterns), array_values($patterns), $export);
if ((bool)$return) return $export; else echo $export;
}
$config = [
'database' => ['host' => 'localhost', 'port' => 3306, 'user' => 'root'],
'app' => ['name' => 'admin', 'url' => 'www.foo.com', 'app' => ['foo']]
];
// 生成合法的PHP代码
$configContent = "<?php\n\nreturn " . varExport($config, TRUE) . ';';
file_put_contents('database.php', $configContent);此时,会在该目录下生成一个database.php文件,内容如下:
php
<?php
return [
'database' => [
'host' => 'localhost',
'port' => 3306,
'user' => 'root',
],
'app' => [
'name' => 'admin',
'url' => 'www.foo.com',
'app' => [
0 => 'foo',
],
],
];serialize
将数组序列化为字符串。
php
$config = [
'database' => ['host' => 'localhost', 'port' => 3306, 'user' => 'root'],
'app' => ['name' => 'admin', 'url' => 'www.foo.com', 'app' => ['foo']]
];
echo serialize($config);unserialize
从已存储的表示中创建 PHP 的值
php
$config = [
'database' => ['host' => 'localhost', 'port' => 3306, 'user' => 'root'],
'app' => ['name' => 'admin', 'url' => 'www.foo.com', 'app' => ['foo']]
];
function cache(string $name, array $data = null)
{
$file = md5($name) . '.php';
if (is_null($data)) {
$content = is_file($file) ? file_get_contents($file) : null;
return unserialize($content) ?: null;
} else {
return file_put_contents($file, serialize($data));
}
}
cache('database', $config);
var_dump(cache('database'));