写代码时候经常遇到这种情况:页面上有好几个变量,想把它们一起塞进数组里方便传递。比如往视图层传数据、记录日志、打包返回给前端。
compact()就是干这个的——根据变量名把变量本身的值抓出来,组装成关联数组。变量名变成键,变量值变成对应的值。
语法格式
array compact(mixed $varname1 [, mixed $... ]): array
参数说明:
| 参数 | 说明 | 必填? |
|---|---|---|
| varname1 | 变量名(字符串)或包含多个变量名的数组 | 必填 |
| varname2... | 更多变量名或数组 | 可选 |
返回值: 打包后的关联数组。
两个特点
-
参数灵活:可以一个个传字符串变量名,也可以传数组,甚至可以混着来
-
自动跳过:传的参数如果对应不上任何已定义的变量,直接跳过不报错
示例1:基础用法
<?php
$product_name = "机械键盘";
$price = 299;
$stock = 45;
$brand = "罗技";
$data = compact("product_name", "price", "stock");
print_r($data);
?>
输出:
Array
(
[product_name] => 机械键盘
[price] => 299
[stock] => 45
)
只打包了前三个变量,$brand没写进去。传什么变量名就打什么包。
示例2:用数组一次性传多个变量名
<?php
$user_id = 10086;
$username = "代码号001";
$email = "code001@example.com";
$level = 5;
$points = 1280;
$fields = ["username", "email", "points"];
$user_info = compact($fields, "user_id");
print_r($user_info);
?>
输出:
Array
(
[username] => 代码号001
[email] => code001@example.com
[points] => 1280
[user_id] => 10086
)
数组和单个字符串可以混着用,compact()会自己解析。
示例3:变量不存在的情况
<?php
$city = "上海";
$district = "浦东";
// $country 这个变量根本没定义过
$result = compact("city", "country", "district");
print_r($result);
?>
输出:
Array
(
[city] => 上海
[district] => 浦东
)
注意:$country对应的"country"被直接忽略了,不报错也不警告。这是一个容易被忽略的细节,变量名拼写错了你都不知道。
我早期调试一个模板渲染问题查了俩小时,之后发现是compact()里变量名写错了一个字母,函数也没报错,就默默跳过了。建议用compact()之前先确认变量确实存在。
示例4:代码号学习编程场景
<?php
// 模拟从数据库或表单获取的数据
$student_name = "张伟";
$student_score = 87;
$student_class = "软件工程3班";
$student_grade = "B";
// 准备返回给前端的数据
$response_data = compact("student_name", "student_score", "student_class", "student_grade");
// 再手动加一些额外信息
$response_data["status"] = "success";
$response_data["timestamp"] = date("Y-m-d H:i:s");
print_r($response_data);
?>
compact() vs 手动写数组
// 方式一:手动写数组
$data = [
"name" => $name,
"age" => $age,
"city" => $city
];
// 方式二:用compact()
$data = compact("name", "age", "city");
两种方式结果一样。我自己的习惯是:
-
变量名和键名相同的时候,用compact()更简洁
-
键名和变量名不一致,或者需要对值做处理的时候,手动写数组
个人经验分享
-
典型应用场景:
-
MVC框架里从控制器往视图传数据:
return view('profile', compact('user', 'posts', 'followers')) -
打包多个变量记录日志
-
组装API响应数据
-
批量提取配置变量
-
-
为什么不直接写数组?
-
变量名重复写两遍很烦,compact()只用写一遍
-
代码更干净,尤其是变量多的时候
-
配合extract()可以反过来用(数组解包成变量)
-
-
注意点:
-
只对当前作用域的变量生效。函数内部用compact()只能拿到函数内定义的变量,拿不到全局变量
-
参数传数组时,数组里的元素必须是字符串变量名
-
变量名区分大小写
-
-
和extract()搭配:
-
compact():变量 → 数组
-
extract():数组 → 变量
这俩是对称的操作,一个打包一个解包。
-
示例5:函数作用域问题
<?php
$global_var = "我是全局的";
function testCompact() {
$local_var = "我是局部的";
// 拿不到$global_var,作用域不同
$result = compact("local_var", "global_var");
print_r($result);
}
testCompact();
?>
输出:
Array
(
[local_var] => 我是局部的
)
globalvar在函数内不存在,所以被跳过。要想在函数内拿到全局变量,需要用‘globalglobalvar在函数内不存在,所以被跳过。要想在函数内拿到全局变量,需要用‘globalglobal_var;先声明或者用$GLOBALS`数组。
本节课程知识要点
-
compact()根据变量名创建关联数组,变量名做键、变量值做值 -
参数可以是字符串变量名,也可以是包含多个变量名的数组,支持混用
-
找不到对应变量时自动跳过,不报错——这是个双刃剑
-
只对当前作用域内的变量生效
-
从PHP 4.0开始可用
-
常见于MVC框架的视图数据传递